【发布时间】:2015-06-19 00:19:35
【问题描述】:
我正在开发的 Ruby on Rails 应用程序允许 users 创建 agendas 并与其他 users 共享。
此外,我们必须能够:
- 在他的个人资料中为每个
user显示agendas列表 - 在议程页面上显示与
agenda关联的users列表 - 与其他用户共享议程时,为该用户定义一个
role,并在上面提到的列表中显示该用户的角色
我打算在 user 和 agenda 模型之间建立一个 has_and_belongs_to_many 关联,就像这样:
class User < ActiveRecord::Base
has_and_belongs_to_many :agendas
end
class Agenda < ActiveRecord::Base
has_and_belongs_to_many :users
end
但后来我想知道这是否能让我在给定用户的给定议程页面上获取并显示roles 的@user.agenda.user.role 列表。
而且我认为我可能应该使用has_many :through 关联,例如:
class User < ActiveRecord::Base
has_many :roles
has_many :agendas, through: :roles
end
class Role < ActiveRecord::Base
belongs_to :user
belongs_to :agenda
end
class Agenda < ActiveRecord::Base
has_many :roles
has_many :users, through: :roles
end
虽然我对user 有多个roles(每个agenda 一个)的想法很满意,但我不确定agenda 有几个roles(一个每个user?)。
最后,为了增加混乱,我读到了多态关联,并认为它也可能是一个可行的解决方案,例如,如果这样做:
class Role < ActiveRecord::Base
belongs_to :definition, polymorphic: true
end
class User < ActiveRecord::Base
has_many :roles, as: :definition
end
class Agenda < ActiveRecord::Base
has_many :roles, as: :definition
end
上述任何解决方案听起来都适合这种情况吗?
更新:做一些研究,我偶然发现这篇文章(从 2012 年开始)解释说 has_many :through 是比 has_and_belongs_to_many 更“聪明”的选择。就我而言,我仍然不确定agenda 是否会有很多roles。
更新 2:正如 @engineersmnkyn 在 cmets 中所建议的,解决此问题的一种方法是使用两个连接表。我尝试实现以下代码:
class User < ActiveRecord::Base
has_many :agendas, through: :jointable
end
class Agenda < ActiveRecord::Base
end
class Role < ActiveRecord::Base
end
class Jointable < ActiveRecord::Base
belongs_to :user
belongs_to :agenda
has_many :agendaroles through :jointable2
end
class Jointable2 < ActiveRecord::Base
belongs_to :roles
belongs_to :useragenda
end
我不确定语法。我在正确的轨道上吗?我应该如何定义Agenda 和Role 模型?
更新 3:如果我使用类似的东西会怎样:
class User < ActiveRecord::Base
has_many :roles
has_many :agendas, through: :roles
end
class Role < ActiveRecord::Base
belongs_to :user
belongs_to :agenda
end
class Agenda < ActiveRecord::Base
has_many :roles
has_many :users, through: :roles
end
然后,在迁移文件中,使用以下内容:
class CreateRoles < ActiveRecord::Migration
def change
create_table :roles do |t|
t.belongs_to :user, index: true
t.belongs_to :agenda, index: true
t.string :privilege
t.timestamps
end
end
end
我能否调用@user.agenda.privilege 来获得给定用户对给定议程的权限(创建者、编辑者或查看者的“角色”)?
相反,我可以调用@agenda.user.privilege 吗?
【问题讨论】:
-
为什么不通过属于用户和议程的连接表设置用户拥有多个议程,并通过属于用户议程和角色的连接表具有多个议程角色。我会为你写下来,但我现在不在电脑前。
-
感谢@engineersmnky 这很有意义,因为它解决了议程没有很多角色的问题。如果我正确理解您的建议,代码将类似于:repl.it/tNS 不过我不确定语法。
标签: ruby-on-rails activerecord database-design has-and-belongs-to-many polymorphic-associations