最好的Rails 3.1练习复杂的查询

时间:2011-12-16 15:45:58

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

假设:

(型号):

Contract (has_many :invoices, belongs_to :user)
Invoice (belongs_to :contract)

这样,例如:

my_contracts = Contract.where(user_id: current_user.id) #=> [#<Contract id: 1, title: "1">, #<Contract id: 2, title: "2">]

在这种情况下,我们有两个用户合同。每份合同都有多个发票。

现在我们需要为每个合同收集所有发票并按'updated_at'对它们进行排序。 类似的东西:

all_invoices = my_contracts.map{|i| i.invoices.sort_by(&:updated_at)}

但使用ActiveRecord。

如何做到对不对?

2 个答案:

答案 0 :(得分:1)

你这样做的方式也不错,只需使用includes来获取发票的急切加载而不是懒惰(n + 1)加载

contracts = Contract.where(:user_id => current_user.id).includes(:invoices)
# or this might do the same => current_user.contracts.includes(:invoices)
invoices = contracts.map{|i| i.invoices }

invoices.sort_by(&:updated_at).each do |invoice|
    # ....
end

试试这个以及David Sulc发布的内容,查看生成的sql并在rails console中试验结果;使用联接vs包含有非常不同的行为,取决于情况一个可能比另一个

更好

另见

答案 1 :(得分:0)

应该是

Invoice.joins(:contracts).where(user_id: current_user.id).order(:updated_at)

Arel不是我的强力套装(仍然需要处理它),但如果这不起作用,至少应该让你更接近答案。