2011-03-23 287 views
1

警告:Total Rails Newb(TRN)。這應該是一個非常基本的問題,所以我希望有人可以騰出幾分鐘來幫助解決一些問題。Has_many,通過關聯

比方說,我有以下型號:用戶,組和成員 一個用戶可以有許多組(比如說朋友,家人等) 一個組可以有很多成員,即其他用戶。

我該如何構造它?

起初我嘗試這樣:

class User < ActiveRecord::Base 
    has_many :groups 
    has_many :groups, :through => :members 
end 

class Groups < ActiveRecord::Base 
    has_many :users, :through => :members 
    belongs_to :user 
end 

class Member < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user 
end 

然而,這給了我一個錯誤的用戶,所以我改變

has_many :groups, :through => :members 

has_many :memberships, :through => :members, :source => :groups 

仍然得到關於失蹤關聯時出錯我試着做

group = Group.new 
group.user.new 

回答

6

這將是有用的:http://railscasts.com/episodes/47-two-many-to-many

class User < ActiveRecord::Base 
    has_many :members 
    has_many :groups, :through => :members 
    has_many :groups_as_owner, :class_name => "Group" 
end 

class Groups < ActiveRecord::Base 
    has_many :members 
    has_many :users, :through => :members 
    belongs_to :owner, :class_name => "User", :foreign_key => :user_id 
end 

class Member < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user 
end 
+0

爲什麼當您調用'user.groups'時,它是否會在返回的數組中多次顯示該組?例如,如果一個組中有2個成員並且調用了'user.groups',那麼該組將在數組中顯示兩次,因爲它與2個成員關聯。 – iwasrobbed 2011-03-24 02:23:41

+1

因爲這是自然行爲。它不會返回uniq組,而是與成員一樣多的所有關聯組。您始終可以調用'user.groups.uniq'或通過'DISTINCT' sql來爲用戶返回uniq組。但實際上你所談論的問題實際上與驗證有關。您應該驗證您創建的數據的唯一性。 – fl00r 2011-03-24 09:18:13

+0

那麼,它不會在數據庫中創建多個「組#2」,因此所有的組ID在數據庫中都是唯一的,它不應該是驗證的事情。自從它與成員關聯以來,它只是多次返回獨特的組。所以你可能正確地使用'user.groups.uniq'來返回一個唯一的集合。感謝您解釋 – iwasrobbed 2011-03-24 13:04:27

2

基本的has_many,通過協會是N:M協會(加入表),其(將)具有不僅僅是ID的加入記錄的ID的更多屬性.. 。

,所以你有一個表組(一個id),一表的用戶(一個ID)和表名(沒有ID,但USER_ID和GROUP_ID)

基本上,你做了什麼幾乎是正確的,只需考慮你如何從用戶訪問一個組,或者反之亦然。 ..

用戶會首先查找其成員信息,並通過會員信息獲取訪問組信息......反之爲一組

,所以你先設置

has_many :members 

然後調用

has_many :groups, :through => :members 

所有你需要的是

class User < ActiveRecord::Base 
    has_many :members 
    has_many :groups, :through => :members 
end 

class Groups < ActiveRecord::Base 
    has_many :members 
    has_many :users, :through => :members 
end 

class Member < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user 
end 

,你有以上

在你的代碼中的另一個bug,你可能想使用

user = group.users.new 

,而不是

user = group.user.new 
+1

再次我幾秒鐘太慢了:-) – Ingo 2011-03-23 10:52:07

1

試試這個結構:

class User < ActiveRecord::Base 
    has_many :members 
    has_many :groups, :through => :members 
end 

class Groups < ActiveRecord::Base 
    has_many :members 
    has_many :users, :through => :members 
end 

class Member < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user 
end 

也請看has_and_belongs_to_many,如果您不需要班級會員,那麼您應該使用has_and_belongs_to_many。在這種情況下,請不要忘記在數據庫中創建連接表

+0

has_and_belongs_to_many現在經常被has_many替代:通過因爲人們發現(正如我從真實經歷中知道的那樣),經常以什麼作爲與兩個簡單鏈接表開始ID很快就會發生變化,以反映出需要的附加屬性,即使只是日期字段也是如此。 – 2011-07-09 12:16:11