查询ARel的关系

时间:2011-04-27 10:16:44

标签: ruby-on-rails ruby-on-rails-3 arel

我正在做这样的事情:

@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子句来解决上述问题。有什么想法吗?

我不能把这一切都放到一个类方法中,因为orderwhere用于其他代码路径,我必须为这个特殊情况复制它们(是不对的。)

修改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 })
}

我还添加了invoicednot_invoiced的范围,因此我现在可以在我的控制器中执行@invoices.invoiced.academic,这更加清晰。

1 个答案:

答案 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