造型相同型号之间两种不同的关系(Modelling two different relationsh

2019-10-23 13:37发布

两种模式组织和用户有一个1:一对多的关系,其中一个组织有多个用户(会员;用户也不能与任何组织):

class Organization < ActiveRecord::Base
  has_many :users, dependent: :destroy
  accepts_nested_attributes_for :users, :reject_if => :all_blank, :allow_destroy => true
  validates_associated :users
end

class User < ActiveRecord::Base
  belongs_to :organization, inverse_of: :users
end

一切工作,测试各种通过。
现在我加入了主持人功能,用户可以有(多)组织版主权限的附加关系。 因此,许多:通过第三模型,我命名为主持人一对多的关系:

class Organization < ActiveRecord::Base
  has_many :users, dependent: :destroy
  accepts_nested_attributes_for :users, :reject_if => :all_blank, :allow_destroy => true
  has_many :moderators, class_name: "Moderator", foreign_key: "reviewee_id", dependent: :destroy
  has_many :users, through: :moderators, source: :reviewer
  validates_associated :users
end

class User < ActiveRecord::Base
  belongs_to :organization, inverse_of: :users
  has_many :moderators, class_name:  "Moderator",   foreign_key: "reviewer_id", dependent: :destroy
  has_many :organizations, through: :moderators, source: :reviewee
end

class Moderator < ActiveRecord::Base
  belongs_to :reviewee, class_name: "Organization"
  belongs_to :reviewer, class_name: "User"
end

我故意用reviewerreviewee名。 如果我只想用user_idorganization_id ,虽然这可能会搞乱了在主持人的模式,我。 因为如果你再参考@user.organization那就不是被定义为使用的关系。 难道使用1:用户和组织,或许多之间有很多关系:通过很多关系......? 通过使用许多不同的名称:通过很多关系, @user.organization应该指的是1:许多关系,同时@user.reviewee例如应该指的是多方面的:通过很多关系。

然而,这个实施后,顿时测试各种失败。 例如:我有签约额外的用户为组织形式。 Clicing按钮传递的organization_ID针对其附加的用户是要创建的形式。 现在突然这个id没有传递的形式和我得到的所有nil错误,因为该组织没有定义(即使该链接依然是如url/member?organization_id=43 )。 而我可以为更多的例子。

因此,似乎有某种冲突,因为新的关系。 也许它无法理解时要使用的多方面的:通过关系多而当1:一对多的关系,即使我用differend评审和reviewee名字...... 有我模仿它不正确或者是不可能有间两种不同的关系同一型号的2?

如果删除了第二has_many :users从组织示范线所有的测试再次通过。 所以,问题似乎是,我有这个关系两次。

Answer 1:

对付一个很好的和常见的模式被称为资源的局部角色。

用户可以在有些情况下的作用范围限定于特定的资源很多角色(父亲,母亲,主持人,草裙舞舞者等)。 像父亲/母亲是范围内的用户(孩子)或主持人可以先限定一个论坛。

就像“系统级”的角色super-admin未作用域的资源也很常见。

class User < ActiveRecord::Base
  has_many :roles
  scope :moderators, ->{ joins(:roles).where( roles: { name: 'moderator' } ) }
  belongs_to :organization
end

# columns: name:string, resource_id:int, resource_type:string, user_id:int
class Role < ActiveRecord::Base
  belongs_to :user
  belongs_to :resource, polymorphic: true
end

class Organization < ActiveRecord::Base
  has_many :roles, as: :resource
  has_many :users
  # This is just a relationship to users with a scope
  has_many :moderators, -> { moderators }, class_name: 'User'
end

因此,要添加主持人,我们会做:

organization = Organization.find(1)
organization.roles.create(user: organization.users.find(1), name: 'moderator')

要获得一个组织中的所有版主:

moderators = Organization.find(1).moderators

这里真棒事情是,我们可以用我们的角色类的任何资源 - 而不仅仅是一个组织。 更妙的是,有很大的宝石来提供这种功能,如Rolify 。



文章来源: Modelling two different relationships between the same models