2011-07-29 73 views
3

我想知道如果人們可以分享他們的首選方法,通過其他外鍵過濾has_many關係的內容。例如,假設您有三個實體:部門,員工,項目。一個部門有很多員工,一個項目有很多員工。我有一個項目,我想從一個給定的部門獲得所有員工。我的代碼如下所示:Rails:通過另一個外鍵過濾has_many關係

# department.rb 

has_many :employees 

# employee.rb 

belongs_to :department 
belongs_to :projects 

# project.rb 

has_many :employees 

現在我能想到的四種方法我的問題:

方法1:類查詢方法:

# anywhere.rb 

Employee.where(:project_id => project, :department_id => department) 

方法2:輔助方法

# project.rb 

def employees_from_department(department) 
    employees.select { |emp| emp.department == department } 
end 

方法3:關係上的輔助方法

# project.rb 

has_many :employees do 
    def from_department(department) 
    where(:department_id => department) 
    # Could also be all.select { |emp| emp.department == deparment } 
    end 
end 

APPROACH 4:作用域

# employee.rb 

scope :from_department, lambda { |department| 
    where(:department_id => department) 
} 

# anywhere.rb 

project.employees.from_department(department) 

我幾乎總是選擇方法#4,因爲它是最可重複使用的。我可以將該範圍應用於任何返回Employees的查詢。我可以將它與其他作用域相結合,設置排序等。另外使用作用域意味着我所有的只讀查詢式代碼都被命名得相當一致並且組織在頂部,所以我的方法更少。範圍是我最喜歡的Rails功能之一。但是我發現自己一直在寫/他們,所以我幾乎得到了一個參數化的範圍來匹配每一個:belongs_to。這是正確的方法嗎?此外,似乎我正在生成大量的數據庫查詢,所以我想知道是否打敗了Rails可能爲我完成的任何緩存,因爲我的作用域每次都迫使Rails去數據庫。

部分地,這是一個性能問題,這意味着沒有萬能的答案,您需要測試生產中的代碼以找到正確的方法。但是在你的代碼在生產之前,你傾向於選擇什麼方法?或者是別的什麼?

+0

#1,#3應該產生相同的SQL(除非你在#3使用'all.select')。至於#4,「項目」在哪裏?不要使用#2,它會檢索過多的數據,在這種情況下,'employees.find(:all,:conditions => ...)'或'.find_by _...'或者可能'where'更好。 –

+0

@Victor:我調整了#4的代碼以顯示如何使用範圍。 –

回答

2

我個人更喜歡範圍(方法4)或類方法。

project.employees.from_department(department_id) 

你可以嘗試將.to_sql呼叫控制檯添加到它:

我相信,在正常情況下,你的方法4和方法,如果您使用鏈接的範圍,像1應該產生相同的SQL語句,看到生成的實際sql。

對於性能(sql)分析,可以使用諸如query-reviewerrack-bug之類的工具,這些工具非常方便且有用。

+0

我同意#1和#4應該生成相同的SQL。感謝您使用SQL分析工具的鏈接! –

1
project.employees.find_by_department_id(department) 

(基本相同#3)