在您的示例中,每个模型类仅代表数据库记录的这些实例之一,即您的 Meter 类仅代表 meters 表中的一个 meter 行。因此,考虑到这一点,您可以看到 meter has_many contracts 的声明意味着每个 meter 实例都有许多 contracts。
让我们分解这条线:@customer.meters.contracts
你有你的@customer 实例并且你正在向它询问它的所有仪表:@customer.meters。 meters 方法的返回是属于 @customer 的 meters 的集合。因为它是一个有很多合约的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