我正嘗試設置一個多態與ActiveRecord的多對多關係。這裏的最終目標:Rails中的多態多對多關係
- 用戶可以屬於很多組織和許多球隊
- 組織有很多用戶和很多球隊
- 隊有許多用戶,屬於一個組織
我想使用has-many-through而不是has-and-belong-to-many,因爲我需要關聯一些信息alon g與關係(如組織或團隊中的用戶角色),所以我做了一個連接表成員。
我該如何實施?
我正嘗試設置一個多態與ActiveRecord的多對多關係。這裏的最終目標:Rails中的多態多對多關係
我想使用has-many-through而不是has-and-belong-to-many,因爲我需要關聯一些信息alon g與關係(如組織或團隊中的用戶角色),所以我做了一個連接表成員。
我該如何實施?
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
因此,比較符合您的要求:
用戶可以屬於多個組織和許多球隊
=>好
組織有許多用戶和許多球隊
=>好
團隊擁有衆多用戶,屬於一個組織
=>好
順便說一下,我們不使用這裏的任何多態性,TeamMember
代表Membership
在你的早期想法!
對於多態關聯,
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
。
在我的項目中,我使用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
。
我厭倦了不得不做的所有設置,所以在我的寶石,我創建了一個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
以及所有的多態關聯和方法爲我自動設置。
對不起,很長的答案。希望你找到有用的東西。