2016-03-07 148 views
0

我正嘗試設置一個多態與ActiveRecord的多對多關係。這裏的最終目標:Rails中的多態多對多關係

  • 用戶可以屬於很多組織和許多球隊
  • 組織有很多用戶和很多球隊
  • 有許多用戶,屬於一個組織

我想使用has-many-through而不是has-and-belong-to-many,因爲我需要關聯一些信息alon g與關係(如組織或團隊中的用戶角色),所以我做了一個連接表成員

我該如何實施?

回答

2

我會設計出這樣的模式: enter image description here

  • Organization有許多Team
  • Team有許多TeamMember
  • User有許多TeamMember
  • TeamMember屬於UserTeam

的車型將是:

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在你的早期想法!

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間接關聯TeamOrganization,並且每次調用都必須經過Membership

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

我厭倦了不得不做的所有設置,所以在我的寶石,我創建了一個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 

以及所有的多態關聯和方法爲我自動設置。

對不起,很長的答案。希望你找到有用的東西。