我正在做这样的事情:
@invoices = Invoice.order(:due_date)
@invoices = @invoices.where(:invoiced => true)
现在,我想通过相关模型的ID过滤发票(我只需要发票项目所有者的ID与某个ID匹配的发票)。目前我正在这样做:
owner_id = #get owner_id somehow
@invoices = @invoices.find_all do |invoice|
invoice.project.owner_id == owner_id
end
当然,这有点乱,我在控制器中这样做,我宁愿不这样做。此外,它打破了ARel的整个观点。我不知道如何使用ARel where
子句来解决上述问题。有什么想法吗?
我不能把这一切都放到一个类方法中,因为order
和where
用于其他代码路径,我必须为这个特殊情况复制它们(是不对的。)
修改:this related question看起来我可能需要使用MetaWhere来干净利落地完成此操作。想法?
编辑2:我选择了fl00r's answer,为发票添加了一个范围:
#invoice.rb
scope :academic, lambda {
academic_id = #get academic_id somehow
joins(:project).where(:projects => { :owner_id => academic_id })
}
我还添加了invoiced
和not_invoiced
的范围,因此我现在可以在我的控制器中执行@invoices.invoiced.academic
,这更加清晰。
答案 0 :(得分:3)
@invoices = Invoice.order(:due_date).joins(:project).
where(:invoiced => true, :projects => {:owner_id => owner_id})
# you can also uniq the list
@invoices.uniq!
<强> UPD 强>
你也可以采取另一种方式
@owner = Owner.find_some
@invoices = @owner.projects.include(:invoices).map(&:invoices).flatten
甚至重构一下:
class Owner < AR::Base
has_many :projects
has_many :invoices, :through => :projects
end
@invoices = @owner.invoices