わかりました、関連付けの api doc を徹底的に読んだ後、どうにかして違いを理解することができました。特に次のセクション: Association join modelおよびAssociationの Eager loading
実際、それらは 2 つの完全に異なる概念と関係があります。
:throughオプションを使用すると、コード内にショートカットを作成できます。上記の (質問) の例では、次の命令で LineItem コレクションを読み取ることができます。
@customer.lineitems
それ以外の
@customer.orders.lineitems
このような属性は読み取り専用であることに注意してください。.
========
:includeオプションを使用すると、さまざまな属性/メソッドにアクセスするときにデータベース内で生成されるクエリの数を減らすことができます。
関連付けに :include を使用すると、次のコードで DB に1 つのクエリが生成されます。
@customer.orders.lineitems
:include がないと、DB に2 つのクエリが生成されます
述べる
hereで説明されているように、モデルがそのようなオプションを使用しない場合、クエリで直接 :include オプションを使用することもできます
上記のモデル定義では、注文ごとに 10 件の品目、顧客ごとに 10 件の注文、および 10 件の顧客があると仮定すると、次のコードは 、関連モデルで :include** オプションを使用せずに101 個のクエリを生成します: .all に対して 1 つ、顧客ごとに 1 つの注文、および注文ごとに 1 つの項目
(= 1 + (10 の顧客 - 注文 x 10 の注文 - 項目) .
Customer.all.each do |customer|
customer.orders.each do |order|
puts "order number : " + order.number
order.lineitems.each do |lineitem|
puts "Item code : " + lineitem.code
end
end
end
このコードは、直接使用されるインクルードを含む12 のクエリ を生成します。1 つは .first に、1 つは order_id と参照された注文を収集するために同時に、10 の注文ごとに 1 つの .lineitems です。
Customer.includes(:orders).each do |customer|
customer.orders.each do |order|
puts "order number : " + order.number
order.lineitems.each do |lineitem|
puts "Item code : " + lineitem.code
end
end
end
注文コレクションは、顧客コレクションと同時に取得されます (LEFT OUTER JOIN sql クエリを使用)。