我应该如何在红宝石中处理这种关系?

时间:2015-10-14 18:10:51

标签: ruby-on-rails ruby activerecord

我一直在前进,我想要一些建议。

我有“用户”可以成为许多“组织”的一部分,并且每个人都可以拥有许多“角色”。 (实际上我和其他类型的用户一起重复了这个场景,并且有类似角色的东西,但是为了这个例子我总结了一下)。

我的初始方法是使用user_id,organization_id和role_id执行表,但这意味着许多具有相同user_id和organization_id的寄存器只是为了更改role_id。

所以我想到了一个organization_users关系表和一个organization_users_roles关系。问题是,现在我并不完全知道如何编码模型。

i = 0
for type in types:
  if (type == 'animal'):
    print (stuffs[i])
  i = i + 1

如果我想得到:'OrganizationUser.first.roles'我收到错误说:PG :: UndefinedTable:错误:关系“organization_user_roles”不存在

我该如何修理模型?

3 个答案:

答案 0 :(得分:3)

您应该使用更简单的方法。根据您的说明,Roles实际上是将UsersOrganizations相关联的内容,反之亦然。

使用has_manyhas_many :through关联,可以像下面这样实现:

class User < ActiveRecord::Base
  has_many :roles, inverse_of: :users, dependent: :destroy
  has_many :organizations, inverse_of: :users, through: :roles
end

class Organization < ActiveRecord::Base
  has_many :roles, inverse_of: :organizations, dependent: :destroy
  has_many :users, inverse_of: :organizations, through: :roles
end

class Role < ActiveRecord::Base
  belongs_to :user, inverse_of: :roles
  belongs_to :organization, inverse_of: :roles
end

如果您希望在销毁用户或组织时保留角色,请将dependent:密钥更改为:nullify。如果您在Role中添加其他描述性数据并希望角色保留,即使用户暂时腾空,这可能是一个好主意。例如。

has_many :through关联参考:

http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

答案 1 :(得分:2)

要添加到jaxx的答案(我投了赞成票),我原本以为你最好看has_many :through

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :positions
   has_many :organizations, through: :positions
end

#app/models/position.rb
class Position < ActiveRecord::Base
   #columns id | user_id | organization_id | role_id | etc | created_at | updated_at
   belongs_to :user
   belongs_to :organization

   belongs_to :role
   delegate :name, to: :role #-> @position.name
end

#app/models/organization.rb
class Organization < ActiveRecord::Base
   has_many :positions
   has_many :users, through: :positions
end

#app/models/role.rb
class Role < ActiveRecord::Base
   has_many :positions
end

这将允许您拨打以下电话:

@organization = Organization.find x
@organization.positions
@organization.users

@user = User.find x
@user.organizations
@user.positions

这比您的方法简单得多,因此更有能力保持您的系统灵活性和安全性。可扩展性。

如果您希望确定@organizations的范围,您应该可以这样做,并仍然可以拨打您需要的users / positions

上述代码的一个额外好处是,Position模型将为您提供可在organizationsusers之间共享的实际数据集。

它解决了jaxx的答案中的一个主要问题,即您必须为您所做的每个关联设置一个角色。根据我的解释,您的roles可以自行设置,每个位置都会分配每个角色提供的权限。

答案 2 :(得分:1)

如果用户可以为单个组织拥有多个Roles, 并且OrganizationUser代表此会员资格, 是的,你需要organization_user_roles的另一个表。

您需要在数据库中显式创建它(通常使用迁移)

为了不让人感到困惑,请尝试为OrganisationUser找一个好名字,比如就业,会员资格等。