我想知道人们在通过其他外键过滤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)
方法二:辅助方法
# project.rb
def employees_from_department(department)
employees.select { |emp| emp.department == department }
end
方法三:在关系上使用帮助方法
# 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
方法4:作用域
# employee.rb
scope :from_department, lambda { |department|
where(:department_id => department)
}
# anywhere.rb
project.employees.from_department(department)
我几乎总是选择 Approach #4,因为它最可重用。我可以将该范围应用于任何返回 Employees 的查询。我可以将其与其他作用域组合使用,设置排序等。此外,使用作用域意味着我所有的只读、查询式代码都命名相当一致,并且组织在顶部,所以我拥有更少的方法。作用域是我最喜欢的 Rails 功能之一。但我发现自己一直在编写它们,以至于我几乎有一个参数化的作用域来匹配每个 :belongs_to。这是正确的方法吗?另外,似乎我正在生成大量的数据库查询,所以我想知道是否我有可能破坏了 Rails 为我完成的任何缓存,因为我的作用域每次都强制 Rails 前往数据库。
在某种程度上这是一个性能问题,这意味着没有一个大小适合所有的答案,你需要测试代码在生产中找到正确的方式。但在你的代码进入生产之前,你倾向于选择哪种方法?或者还有其他方法吗?
all.select
)。至于#4,project
在哪里?不要使用#2,它会检索过多的数据,在这种情况下,employees.find(:all,:conditions => ...)
或.find_by_...
或可能是where
更好。 - Victor Moroz