【问题标题】:ActiveRecord :has_many and includesActiveRecord :has_many 并包括
【发布时间】:2017-05-30 19:54:19
【问题描述】:

我使用的是 rails 4.2.0 - 这是我的模型:

class Customer < ApplicationRecord
  has_many :meters, -> { includes :contracts }
end

class Meter < ApplicationRecord
  belongs_to :customer
  has_many :contracts
end

class Contract < ApplicationRecord
  belongs_to :meter
end

现在,我想显示客户的所有合同。根据Rails Guides,我应该可以做到这一点:

@customer.meters.contracts

但是,它不起作用。这是错误信息:

undefined method `contracts' for #<Meter::ActiveRecord_Associations_CollectionProxy:0x007fb0385730b0>

在这种情况下最好的方法是什么? 感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails ruby activerecord has-many


    【解决方案1】:

    在您的示例中,每个模型类仅代表数据库记录的这些实例之一,即您的 Meter 类仅代表 meters 表中的一个 meter 行。因此,考虑到这一点,您可以看到 meter has_many contracts 的声明意味着每个 meter 实例都有许多 contracts

    让我们分解这条线:@customer.meters.contracts

    你有你的@customer 实例并且你正在向它询问它的所有仪表:@customer.metersmeters 方法的返回是属于 @customermeters 的集合。因为它是一个有很多合约的meter 的实例,所以你不能以这种方式向计量表的集合询问他们的合约。

    您可以询问单个仪表:@customer.meters.first.contracts 或者您可以遍历所有仪表并获取所有合同:

    @customer.meters.flat_map(&:contracts) # => an array of all the contracts
    

    或者,更一般地说,您可能希望在视图中显示客户合同的列表:

    <% @customer.meters.each do |meter| %>
      <% meter.contracts.each do |contract|
        // display the contract
      <% end %>
    <% end %>
    

    但是,您可以通过 meters 关联将所有 contracts 关联到 customer

    class Customer < ApplicationRecord
      has_many :meters, -> { includes :contracts }
      # ActiveRecord's shorthand declaration for associating
      # records through a join table, in this case 'meters'
      has_many :contracts, through: :meters
    end
    

    通过添加has_many X, through: Y,您是说客户记录通过连接表Y 与另一个表X 中的记录相关联。

    有了这个,给定一个customer 和现有的meters 以及那些现有的contracts,您将能够调用@customer.contracts,ActiveRecord 将通过加入客户的meters 来获取contracts与他们的contracts 并返回contracts 集合。

    更多关于 Rails Has Many Through 协会的信息:http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多