【问题标题】:What is the difference between :include and :through options in rails associations?Rails 关联中的 :include 和 :through 选项有什么区别?
【发布时间】:2012-12-10 10:31:51
【问题描述】:

我不明白在哪种情况下我应该使用 :include 选项而不是 :through 选项?

例如,我可以这样编写模型:

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

感谢澄清什么练习匹配哪个选项。

【问题讨论】:

    标签: ruby-on-rails-3.2 model-associations


    【解决方案1】:

    好的,在仔细阅读api doc of associations 后,我设法理解了其中的区别。特别是以下部分:关联加入模型关联的急切加载

    事实上,它们与两个完全不同的概念有关:

    :through 选项允许您在代码中构建快捷方式。 在我上面的(问题)示例中,我可以使用以下指令读取 LineItem 集合:

    @customer.lineitems
    

    而不是

    @customer.orders.lineitems
    

    警告是这样的属性是只读的!

    ========

    :include 选项允许您在访问不同的属性/方法时减少在数据库中生成的查询数量

    在我的关联中使用 :include,以下代码会在我的数据库中生成 一个 查询:

    @customer.orders.lineitems
    

    如果没有 :include ,它会在我的数据库中生成 两个 查询


    备注

    正如here 解释的那样,当模型不使用此类选项时,也可以设法在查询中直接使用 :include 选项

    在我上面的模型定义中,假设每个订单有 10 个订单项,每个客户有 10 个订单,以及 10 个客户,下面的代码将生成 101 个查询,而无需在关联模型中使用 :include** 选项: .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 个查询,其中 includes 直接使用: 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
    

    orders 集合将与 customers 集合同时被检索(使用 LEFT OUTER JOIN sql 查询)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 2023-03-26
      • 2010-12-23
      • 1970-01-01
      相关资源
      最近更新 更多