我正在尝试与ActiveRecord建立多态的has-many-through关系。这是最终目标:
我正在尝试使用has-many-through而不是has-and-belongs-to-many,因为我需要将一些信息与关系(如组织或团队中的用户角色)相关联,所以我做了联接表会员。
我该如何实现?
答案 0 :(得分:2)
Organization
有很多Team
Team
有很多TeamMember
User
有很多TeamMember
TeamMember
属于User
和Team
模型将是:
<强> organization.rb 强>
class Organization < ActiveRecord::Base
has_many :teams
has_many :team_members, through: :teams
has_many :users, through: :team_members
end
<强> team.rb 强>
class Team < ActiveRecord::Base
belongs_to :organization # fk: organization_id
has_many :team_members
has_many :users, through: :team_members
end
<强> user.rb 强>
class User < ActiveRecord::Base
has_many :team_members
has_many :teams, through: :team_members
has_many :organizations, though: :teams
end
<强> team_member.rb 强>
class TeamMember < ActiveRecord::Base
belongs_to :team # fk: team_id
belongs_to :user # fk: user_id
attr_accessible :role # role in team
end
因此,请与您的要求进行比较:
用户可以属于许多组织和许多团队
=&GT;好
组织拥有众多用户和许多团队
=&GT;好
团队拥有许多用户并属于某个组织
=&GT;好
顺便说一下,我们这里不使用任何多态,而TeamMember
代表你早期想法中的Membership
!
答案 1 :(得分:1)
对于多态关联,
class User
has_many :memberships
end
class Team
belongs_to :organization
has_many :memberships, :as => :membershipable #you decide the name
end
class Organization
has_many :memberships, :as => :membershipable
has_many :teams
end
class Membership
belongs_to :user
belongs_to :membershipable, polymorphic: true
end
请注意,User
与Team
和Organization
间接关联,并且每次通话都必须经过Membership
。
答案 2 :(得分:0)
在我的项目中,我使用Relationship
类(在我名为ActsAsRelatingTo
的gem中)作为连接模型。它看起来像这样:
# == Schema Information
#
# Table name: acts_as_relating_to_relationships
#
# id :integer not null, primary key
# owner_id :integer
# owner_type :string
# in_relation_to_id :integer
# in_relation_to_type :string
# created_at :datetime not null
# updated_at :datetime not null
#
module ActsAsRelatingTo
class Relationship < ActiveRecord::Base
validates :owner_id, presence: true
validates :owner_type, presence: true
validates :in_relation_to_id, presence: true
validates :in_relation_to_type, presence: true
belongs_to :owner, polymorphic: true
belongs_to :in_relation_to, polymorphic: true
end
end
所以,在你的User
模型中,你会说:
class User < ActiveRecord::Base
has_many :owned_relationships,
as: :owner,
class_name: "ActsAsRelatingTo::Relationship",
dependent: :destroy
has_many :organizations_i_relate_to,
through: :owned_relationships,
source: :in_relation_to,
source_type: "Organization"
...
end
我相信您可以将source_type
参数关闭,因为可以从Organization
推断出已加入的类(:organizations
)。通常,我会加入无法从关系名称推断出类名的模型,在这种情况下,我包含source_type
参数。
有了这个,你可以说user.organizations_i_relate_to
。你可以为任何一组类之间的关系做同样的设置。
您也可以在Organization
课程中说:
class Organization < ActiveRecord::Base
has_many :referencing_relationships,
as: :in_relation_to,
class_name: "ActsAsRelatingTo::Relationship",
dependent: :destroy
has_many :users_that_relate_to_me,
through: :referencing_relationships,
source: :owner,
source_type: "User"
这样你就可以说organization.users_that_relate_to_me
。
我厌倦了必须完成所有设置,所以在我的gem中我创建了一个acts_as_relating_to
方法,所以我可以做类似的事情:
class User < ActiveRecord::Base
acts_as_relating_to :organizations, :teams
...
end
和
class Organization < ActiveRecord::Base
acts_as_relating_to :users, :organizations
...
end
和
class Team < ActiveRecord::Base
acts_as_relating_to :organizations, :users
...
end
并且为我自动设置所有多态关联和方法&#34;。
很抱歉答案很长。希望你能找到有用的东西。