我正在处理的Ruby on Rails应用允许users
与其他agendas
一起创建和共享users
。
此外,我们必须能够:
agendas
的{{1}}列表
user
相关联的users
列表agenda
,并在上面提到的列表中显示该用户的角色我打算在role
和has_and_belongs_to_many
模型之间使用user
关联,就像那样:
agenda
但后来我想知道这是否会让我在给定用户的给定议程页面上显示class User < ActiveRecord::Base
has_and_belongs_to_many :agendas
end
class Agenda < ActiveRecord::Base
has_and_belongs_to_many :users
end
@user.agenda.user.role
列表。
我认为我应该选择roles
关联,例如:
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
上述任何一种解决方案是否适合这种情况?
更新:做了一些研究,我偶然发现了这篇文章(从2012年开始),解释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
是一个比has_many :through
更“聪明”的选择。就我而言,我仍然不确定has_and_belongs_to_many
会有多少agenda
。
更新2 :正如@engineersmnkyn的评论中所建议的那样,解决这个问题的方法是使用两个连接表。我试图实现以下代码:
roles
我不确定语法。我是在正确的轨道上吗?我应该如何定义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
模型?
更新3 :如果我选择了以下内容,该怎么办?
Role
然后,在迁移文件中,使用以下内容:
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.agenda.privilege来获取给定日程的特定用户的特权(创建者,编辑者或查看者的“角色”)?
相反,我可以打电话给@ agenda.user.privilege吗?
答案 0 :(得分:1)
好的,我会先说我没有测试过这个,但我认为这两个选择中的一个应该适合你。
此外,如果这些连接表永远不需要除了关系之外的功能,那么has_and_belongs_to_many
会更好,更简洁。
基本Rails经验法则:
如果您需要将关系模型作为自己的实体使用,请使用has_many:through。使用遗留模式或直接使用关系本身时,请使用has_and_belongs_to_many。
首先使用您的示例(http://repl.it/tNS):
class User < ActiveRecord::Base
has_many :user_agendas
has_many :agendas, through: :user_agendas
has_many :user_agenda_roles, through: :user_agendas
has_many :roles, through: :user_agenda_roles
def agenda_roles(agenda)
roles.where(user_agenda_roles:{agenda:agenda})
end
end
class Agenda < ActiveRecord::Base
has_many :user_agendas
has_many :users, through: :user_agendas
has_many :user_agenda_roles, through: :user_agendas
has_many :roles, through: :user_agenda_roles
def user_roles(user)
roles.where(user_agenda_roles:{user: user})
end
end
class Role < ActiveRecord::Base
has_many :user_agenda_roles
end
class UserAgenda < ActiveRecord::Base
belongs_to :user
belongs_to :agenda
has_many :user_agenda_roles
has_many :roles, through: :user_agenda_roles
end
class UserAgendaRoles < ActiveRecord::Base
belongs_to :role
belongs_to :user_agenda
end
这使用连接表来保存User&lt; =&gt;的关系。议程然后加入UserAgenda =&gt;表角色。
第二个选项是使用连接表来保存User&lt; =&gt;的关系。议程和另一个联接表来处理用户&lt; =&gt;的关系议程&lt; =&gt;角色。此选项将从CRUD的角度进行更多设置,例如验证用户是否是该议程的用户但允许一点灵活性。
class User < ActiveRecord::Base
has_many :user_agendas
has_many :agendas, through: :user_agendas
has_many :user_agenda_roles
has_many :roles, through: :user_agenda_roles
def agenda_roles(agenda)
roles.where(user_agenda_roles:{agenda: agenda})
end
end
class Agenda < ActiveRecord::Base
has_many :user_agendas
has_many :users, through: :user_agendas
has_many :user_agenda_roles
has_many :roles, through: :user_agenda_roles
def user_roles(user)
roles.where(user_agenda_roles:{user: user})
end
end
class Role < ActiveRecord::Base
has_many :user_agenda_roles
end
class UserAgenda < ActiveRecord::Base
belongs_to :user
belongs_to :agenda
end
class UserAgendaRoles < ActiveRecord::Base
belongs_to :role
belongs_to :user
belongs_to :agenda
end
我知道这是一个很长的答案,但我想在这种情况下向您展示解决问题的方法。希望它有所帮助