2011-04-27 75 views
1
查询关系

我在做这样的事情:在阿雷尔

@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干净地做到这一点。思考?

EDIT2:我去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

回答

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 
+0

完美,谢谢!我会用我的方法更新这个问题。 – Skilldrick 2011-04-27 10:47:17