我有4个型号,A,B,C和D
class A < ActiveRecord::Base
has_many :B
has_many :C, :through => :B
end
class B < ActiveRecord::Base
belongs_to :A
has_many :C
has_many :D, :through => :C
end
class C < ActiveRecord::Base
belongs_to :B
end
class D < ActiveRecord::Base
belongs_to :C
end
我有一个非常天真的实施,这非常明显......
<% A.B.each do |b| %>
<%= b.number %>
<% b.C.each do |c| %>
<%= c.name %>
<% end %>
<% end %>
获得All C for A的最佳方式是什么? 获得All D for A的最佳方式是什么?
我希望使用带有“created_at”值的order_by子句而不是迭代B来获取所有'C'。
可能是我错过了一些ActiveRecord魔法?
我感谢任何帮助。
答案 0 :(得分:6)
首先,您需要进行一些更改。
class C
需要与D
class C < ActiveRecord::Base
belongs_to :B
has_one :D
end
如果您想访问A
的{{1}},则还需要指定此内容。
D
现在,要访问class A < ActiveRecord::Base
has_many :B
has_many :C, :through => :B
has_many :D, :through => :C
end
A
的所有内容:
C
注意调用-> a = A.where(:id => 1).includes(:C).first
A Load (0.2ms) SELECT "as".* FROM "as" WHERE "as"."id" = 1 LIMIT 1
B Load (0.1ms) SELECT "bs".* FROM "bs" WHERE "bs"."a_id" IN (1)
C Load (0.1ms) SELECT "cs".* FROM "cs" WHERE "cs"."b_id" IN (1, 2)
=> #<A id: 1, created_at: "2012-01-10 04:28:42", updated_at: "2012-01-10 04:28:42">
-> a.C
=> [#<C id: 1, b_id: 1, created_at: "2012-01-10 04:30:10", updated_at: "2012-01-10 04:30:10">, #<C id: 2, b_id: 1, created_at: "2012-01-10 04:30:11", updated_at: "2012-01-10 04:30:11">, #<C id: 3, b_id: 2, created_at: "2012-01-10 04:30:21", updated_at: "2012-01-10 04:30:21">, #<C id: 4, b_id: 2, created_at: "2012-01-10 04:30:21", updated_at: "2012-01-10 04:30:21">]
时如何不执行其他查询。这是因为ActiveRecord知道您希望通过a.C
调用访问找到的A
C
,并生成最少数量的查询。同样适用于include
&#39; s:
D
假设您想要所有-> a = A.where(:id => 1).includes(:D).first
A Load (0.1ms) SELECT "as".* FROM "as" WHERE "as"."id" = 1 LIMIT 1
B Load (0.1ms) SELECT "bs".* FROM "bs" WHERE "bs"."a_id" IN (1)
C Load (0.1ms) SELECT "cs".* FROM "cs" WHERE "cs"."b_id" IN (1, 2)
D Load (0.1ms) SELECT "ds".* FROM "ds" WHERE "ds"."c_id" IN (1, 2, 3, 4)
A
,但希望D
订购:
C
注意您也可以将其设置为关联的默认值:
A.where(:id => 1).includes(:C).order('cs.created_at DESC').includes(:D)
选项指示将接收关联对象的顺序(使用SQL:order
子句使用的语法)。ORDER BY