我如何通过两种方式实现has_many:through关联?

时间:2018-08-21 00:36:55

标签: ruby-on-rails activerecord associations

我有一个属性模型和一个用户模型。

具有“ admin”角色(由users表上的列表示)的用户可以具有许多属性。

具有“来宾”角色的用户也可以属于某个属性,从而可以访问该属性。

我应该如何在Rails中做到这一点?

2 个答案:

答案 0 :(得分:0)

授权表-> user_id,property_id

class Authorization < ActiveRecord::Base
    belongs_to :user
    belongs_to :property
end 

class User < ActiveRecord::Base
    has_many :authorizations
    has_many :properties, through: :authorizations
end

class Property < ActiveRecord::Base
    has_many :authorizations
    has_many :users, through: :authorizations
end

然后您可以User.find(id).properties

答案 1 :(得分:0)

首先,您需要在模型UserProperty之间建立has_many :through关联。因此,使用列 user_id propety_id 创建一个新表 properties_users 。并对模型进行以下更改:

class PropertiesUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :property
end 

class User < ActiveRecord::Base
  has_many :properties_users
  has_many :properties, through: :properties_users
end

class Property < ActiveRecord::Base
  has_many :properties_users
  has_many :users, through: :properties_users
end

现在,我们需要确保来宾用户没有多个属性。为此,我们可以向模型PropertiesUser添加验证,如下所示:

class PropertiesUser < ActiveRecord::Base
  validate :validate_property_count_for_guest

  private

  def validate_property_count_for_guest
    return unless user && user.guest?

    if user.properties.not(id: self.id).count >= 1
      self.errors.add(:base, 'guest user cannot have more than one properties')
    end
  end
end 

class User < ActiveRecord::Base
  def guest?
    # return `true` if user is guest
  end
end

最后,要访问来宾用户的属性,请在模型User中定义一个专用方法:

class User < ActiveRecord::Base
  def property
    # Raise error if `property` is called on non-guest users
    raise 'user has multiple properties' unless guest?

    properties.first
  end
end

现在,您可以通过运行以下命令来获取来宾用户的属性:

user = User.first

user.guest?
 => true

user.property
 => <#Property 1>    # A record of Property