まず、いくつかの変更を加える必要があります。
class C
に関連付ける必要がありますD
class C < ActiveRecord::Base
belongs_to :B
has_one :D
end
A
's 'にアクセスする場合はD
、これも指定する必要があります。
class A < ActiveRecord::Base
has_many :B
has_many :C, :through => :B
has_many :D, :through => :C
end
A
ここで、すべての's 'にアクセスするには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">]
を呼び出したときに別のクエリが実行されないことに注意してくださいa.C
。これは、ActiveRecordが、呼び出しによって見つかったにアクセスする必要があることを認識してA
おり、最小数のクエリを生成するためですC
。include
同じことがD
'sにも当てはまります:
-> 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
すべての's D
'が必要だったが、C
'sが注文されたとしましょう。
A.where(:id => 1).includes(:C).order('cs.created_at DESC').includes(:D)
これをアソシエーションのデフォルトとして設定することもできることに注意してください。
この:order
オプションは、関連するオブジェクトを受け取る順序を指定します(SQLORDER BY
句で使用される構文で)。
class Customer < ActiveRecord::Base
has_many :orders, :order => "date_confirmed DESC"
end