2011-12-14 3 views
0

질문이 불충분하면 죄송합니다.활성 레코드 및 레일 3의 배열에 대해 단 수식을 실행하지 않으려면 어떻게해야합니까?

class Employee < ActiveRecord::Base 
    has_many :merged_children, :class_name => 'Employee', :foreign_key => "merge_parent_id" 
    has_many :timesheets 

    def total_time 
    merged_children.timesheets.in_range(range).hours_minutes.sum 
    end 
end 

class Timesheet < ActiveRecord::Base 
    belongs_to :employee 

    def in_range(range) 
    # filter records based on transaction_date in range 
    end 

    def hours_minutes 
    (hours + minutes/60.0).to_f 
    end 
end 

참고 : 그래서 같은 간체 모델 레일 3.1 앱 가지고 in_range 방법은 본질적 범위로서 작용하고 hours_minutes가 계산된다. hours_minutes는 결과 데이터 집합의 각 작업 표 기록에 유효하며 total_time은 해당 값을 합하여 금액을 반환해야합니다.

employee.merged_children이 배열을 반환하고 작업 표가 단일 Employee 객체에 대해 실행되기 때문에 "total_time"메소드가 작동하지 않습니다.

"total_time"을 구조화하여 여전히 하나의 쿼리를 db로 전송하는 방법이 있습니까? merged_children 배열을 반복하여 각각에 대한 쿼리를 발행하는 것은 좋지 않습니다. Arel 테이블에 대한 직접적인 호출이 도움이되거나 상처를 입을 지 확신 할 수는 없지만 아이디어에 대해 열려 있습니다.

우리가 바로, 그 결과 SQL 효과적으로처럼 보일 것이다 얻을 경우 너무 많은

SELECT sum(hours + minutes/60.0) 
FROM employees e1 join employees e2 on e1.id = e2.merge_parent_id join timesheets t on t.employee_id = e2.id 
WHERE e1.id = [@employee.id] and t.transaction_date BETWEEN [@range.begin] and [@range.end] 

감사합니다!

답변

0

여기 쉬운 일이 당신의 직원 모델에

has_many :children_timesheets, :through => :merged_children, :source => :timesheets 

를 추가 할 수 있습니다에 대한 그래서 희망이, 그리고

을 더 좋은 뭔가를 반환합니다 (가정 in_range 실제로 범위, 또는 클래스 메소드입니다 그는 발견)

children_timesheets.in_range(...) 

가 관심있는 작업 표를 수집 할 수 있어야하지 당신은

과 같은 작업을 수행 할 수 있습니다
+0

이것은 완벽합니다. 우리는 이것을 정확하게 사용하는 것으로 끝 맺었습니다. 정말 고마워. – adamrneary

0

실제 데이터로 테스트되지 않았습니다.

range = ((1.day.ago)...(2.days.ago)) 
    merge_parent = Employee.find(some_id) 

    Timesheet.where(:transaction_date => range) 
    .joins(:employee).where(:employees => {:merge_parent_id => merge_parent.id}) 
    .sum('hours*60 + minutes') 

    (0.3ms) SELECT SUM(hours*60 + minutes) AS sum_id FROM "timesheets" INNER JOIN "employees" ON "employees"."id" = "timesheets"."employee_id" WHERE "employees"."merge_parent_id" = 1 AND ("timesheets"."created_at" >= '2011-12-13 03:04:35.085416' AND "timesheets"."created_at" < '2011-12-12 03:04: 

"0"을 반환합니다. 당신이

+0

이것은 환상적인 출발점이며, 현재 우리가 있어야 할 곳을 찾기 위해 놀고 있지만 핵심 과제는 total_time 메소드가이 경우 Employee 클래스에 존재하도록하는 것입니다. 객체 지향적 인 플레이는 직원이 작업 표 클래스에서 쿼리를 가져와야하는 것보다 자신의 전체 시간이 무엇인지를 "알아야"한다는 것입니다. 이견있는 사람? (고마워!) – adamrneary