同一模型上的多个关联

时间:2018-01-27 11:59:49

标签: ruby-on-rails associations

我有一个企业和用户的模型。企业可能有多个经理,但这些经理中只有一个可以是所有者。我试图建模如下:

class Business < ApplicationRecord
   has_many :managements
   has_many :managers, through: :managements, source: :user, autosave: true
   has_one :ownership, -> { where owner: true },
                 class_name: 'Management',
                 autosave: true
   has_one :owner, through: :ownership, source: :user, autosave: true
end
class Management < ApplicationRecord
  belongs_to :user
  belongs_to :business
end
class User < ApplicationRecord
  has_many :managements
  has_many :businesses, through: :managements
end

在我尝试保存业务之前,这一切似乎都运行良好:

business.owner = owner
#<User id: nil, email: "owner@example.com", password_digest: "$2a$04$aXswT85yAiyQ/3Pa2QAMB.4eDs9JPikpFfb8fJtwsUg...", confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, created_at: nil, updated_at: nil>
business.ownership
#<Management id: nil, user_id: nil, business_id: nil, owner: true, created_at: nil, updated_at: nil>
(byebug) business.owner
#<User id: nil, email: "owner@example.com", password_digest: "$2a$04$aXswT85yAiyQ/3Pa2QAMB.4eDs9JPikpFfb8fJtwsUg...", confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, created_at: nil, updated_at: nil>
(byebug) business.valid?
false
(byebug) business.errors
#<ActiveModel::Errors:0x007f9ef5ca5148 @base=#<Business id: nil, longitude: #<BigDecimal:7f9ef2c23e48,'0.101E3',9(27)>, latitude: #<BigDecimal:7f9ef2c23d58,'-0.23E2',9(27)>, address: "line 1, line2, town, county", postcode: "B1 1NL", business_name: "Business 1", deleted_at: nil, created_at: nil, updated_at: nil>, @messages={:"ownership.business"=>["must exist"]}, @details={:"ownership.business"=>[{:error=>:blank}]}>

我不明白ownership.business关系是什么?我能做些什么来完成这项工作?

我正在使用rails 5.0.6。

1 个答案:

答案 0 :(得分:1)

尝试将inverse_of: :business附加到has_one :ownership

has_one :ownership, -> { where(owner: true) },
                 class_name: 'Management',
                 autosave: true,
                 inverse_of: :business

documentation开始,:inverse_of选项似乎是一种避免SQL查询而不生成SQL查询的方法。它提示ActiveRecord使用已加载的数据,而不是通过关系再次获取数据。

我认为:inverse_of在您处理尚未保留的关联时非常有用。

  • 如果没有:inverse_of个参数,ownership.business将返回nil,因为它会触发sql查询并且数据尚未存储。
  • 使用:inverse_of参数,从内存中检索数据。