-1

どのような場合に :through オプションの代わりに :include オプションを使用すべきかわかりません。

たとえば、次のようにモデルを記述できます。

Class Customer < ActiveRecord::Base
  has_many :orders, :include => :line_items
end

class Order < Active Record::Base
  belongs_to :customer
  has_many :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :order
end

または、次のように記述できます。

Class Customer < ActiveRecord::Base
  has_many :orders
  has_many  :lineitems, :through => :orders
end

class Order < Active Record::Base
  belongs_to :customer
  has_many :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :order
end

どの練習がどのオプションに一致するかを明確にしていただきありがとうございます。

4

1 に答える 1

0

わかりました、関連付けの 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 クエリを使用)。

于 2012-12-14T17:27:00.660 に答える