造型相同的模型之间两种不同的关系 [英] Modelling two different relationships between the same models

查看:166
本文介绍了造型相同的模型之间两种不同的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两种模式组织和用户有一个1:一对多的关系,其中一个组织有多个用户(会员;用户还可以的的关联,以任何组织):

Two models Organization and User have a 1:many relationship, where an organization has multiple users (members; a user can also not be associated to any organization):

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

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

Everything worked, all sorts of tests pass.
Now I added an additional relationship for a moderator function, where users can have moderator rights for (multiple) organizations. Hence, a many:many relationship through a third model, which I named Moderator:

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

我故意使用了审核 reviewee 名称。如果我只是在主持人模型中使用 USER_ID organization_id ,我虽然这可能会误事。因为如果你再参考 @ user.organization 那就不是被定义为使用的关系。难道使用1:用户和组织,或者很多很多之间的关系:通过很多关系......?通过使用不同的名称很多:通过关系很多, @ user.organization 应该指的是1:一对多的关系,而 @ user.reviewee 例如应该是指很多:很多关系,通过

I intentionally used the reviewer and reviewee names. If I would just use user_id and organization_id in the Moderator model, I though this could mess things up. Because if you would then refer to @user.organization then it wouldn't be defined which relationship to use. Would it use the 1:many relationship between user and organization, or the many:many through relationship...? By using different names for the many:many through relationship, @user.organization should refer to the 1:many relationship, while @user.reviewee for example should refer to the many:many through relationship.

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

Nevertheless, after this implementation, suddenly all sorts of tests fail. For example: I have a form that signs up an additional user for an organization. Clicing a button passes the organization_id to the form for which an additional user is to be created. Now suddenly this id doesn't get passed on to the form and I get all nil error because the organization isn't defined (even though the link still is e.g. url/member?organization_id=43). And I could give many more examples.

所以,似乎有某种冲突,因为新的关系。也许是不明白何时使用多比多通过关系,当1:一对多的关系,即使我用differend评审和reviewee名称... 有我模仿它不正确或已不可能有两个同一型号的2之间的不同关系?

So there seems to be some kind of conflict because of the new relationship. Perhaps it fails to understand when to use the many:many through relationship and when the 1:many relationship, even though I used the differend reviewer and reviewee names... Have I modelled it incorrectly or is it impossible to have two different relationships between 2 of the same models?

如果我删除第二个的has_many:用户从组织模型的所有测试再次通过线。所以,问题似乎是,我有这个关系的两倍。

If I remove the second has_many :users line from the Organization model all tests pass again. So the problem seems to be that I have this relationship twice.

推荐答案

有关处理一个很好的和共同的模式被称为资源的局部角色。

A good and common pattern for dealing with this is called resource scoped roles.

一个用户可以在某些案件中的作用范围限于特定的资源很多角色(父亲,母亲,主持人,草裙舞舞者等)。像父/母的作用范围是用户(孩子)或主持人可以作用域到论坛。

A User can have many roles (father, mother, moderator, hula-dancer etc) in some cases the Role is scoped to a particular resource. Like father/mother is scoped to a User (the child) or a moderator can be scoped to a Forum.

拥有一个像系统级的角色而不是作用域资源超级管理员也很常见。

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

所以要加一个主持人,我们会做:

So to add a moderator we would do:

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

要获得所有版主的组织:

To get all moderators for a organization:

moderators = Organization.find(1).moderators

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

这篇关于造型相同的模型之间两种不同的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆