以http://guides.rubyonrails.org/association_basics.html#self-joins为例,
class Employee < ApplicationRecord
has_many :subordinates, class_name: "Employee", foreign_key: "manager_id"
belongs_to :manager, class_name: "Employee"
end
如果我想申请某个条件,只说员工 is_manager (假设员工有这样的布尔字段) true ,是经理,可以显示下属
如果我只是将上面改为
class Employee < ApplicationRecord
has_many :subordinates, -> {where is_manager: true}, class_name: "Employee", foreign_key: "manager_id"
belongs_to :manager, class_name: "Employee"
end
由于条件where is_manager: true
也适用于subordinates
,因此无效。
FROM `employees` WHERE `employees`.`is_manager` = 1 AND (employees.manager_id = 1)
但我只想申请经理,而不是下属。
像
这样的东西Employee.where(manager_id: employee.where(is_manager: true))
所以,如果我打电话
employee = Employee.find 1
employee.subordinates
首先,它会检查员工是否是经理,如果是,则返回下属;否则,返回空数组
答案 0 :(得分:4)
为什么不创建一个类方法[1],as_manager
。类似的东西:
class Employee < ApplicationRecord
has_many :subordinates, class_name: "Employee", foreign_key: "manager_id"
belongs_to :manager, class_name: "Employee"
class << self
def as_manager
where(is_manager: true)
end
end
end
然后你应该能够做到:
Employee.as_manager.subordinates
或者,考虑到您的业务需求&#39; (非常奇怪,业务部门对此级别的实现细节有要求),您如何抢占subordinates
指令提供的has_many
方法呢?
class Employee < ApplicationRecord
has_many :subordinates, class_name: "Employee", foreign_key: "manager_id"
belongs_to :manager, class_name: "Employee"
def subordinates
is_manager ? where(manager_id: id) : []
end
end
这样,您可以保留has_many
提供的所有其他方法,但获得subordinates
所需的行为。
[1] Jörg W Mittag希望声明:
我是Ruby Purists之一,他们喜欢指出Ruby中没有类方法。但是,我完全没问题,通常使用术语类方法 ,只要所有各方都完全理解这是一种口语用法。换句话说,如果你知道没有类方法和术语&#34;类方法&#34;对于作为
Class
&#34;的实例的对象的单例类的&#34;实例方法,它只是简短的,那么就没有问题。但除此之外,我只看到它阻碍了理解。
让所有各方充分理解, class method 这个术语在上面的口语中使用。