2013-02-28 82 views
0

三種型號:Rails的多個父關係

User 
List 
Item 

一個User可以有很多ListsList可以有很多Items。每個List可以有一個Item由任何User添加到它。這意味着,例如,您可以創建一個列表,並且可以向其中添加項目。合理?我們繼續吧。

我希望能夠在任何時間點找到由X User創建的所有Items

class User < ActiveRecord::Base 
    has_many :lists 
    has_many :items 
end 
class List < ActiveRecord::Base 
    belongs_to :user 
    has_many :items 
end 
class Item < ActiveRecord::Base 
    belongs_to :list 
    belongs_to :user 
end 

我不喜歡這樣。它有一種時髦的氣味,但我不能把它放在手指上。我覺得應該有更好的東西。當創建一個新Item我會寫一些東西,如下所示:

list = List.find(params[:list_id]) 
@item = list.items.new(params[:item]) 
user = User.first 
@item.user = user 
@item.save! 

所以,我缺少什麼?我的關係錯了嗎(很有可能)?告訴我! :)

回答

0

好像有可能是項目和用戶之間不同的關係:由users 1)items添加到lists,和2)listsusers創建。

只有一個用戶可以創建一個列表。許多用戶可以在創建後將項目添加到列表中。

所以造型,這需要兩個不同的關係

class User < ActiveRecord::Base 
    has_many :lists 
    has_many :items_added, :class_name => "Item", :foreign_key => "added_by_user_id" 
end 
class List < ActiveRecord::Base 
    belongs_to :user 
    has_many :items 
end 
class Item < ActiveRecord::Base 
    belongs_to :list 
    belongs_to :added_by_user, :class_name => "User", :foreign_key => "user_id" 
end 

這是有道理的假設你所有這些關係是必需的 - 那就是,一個列表需要時,它的創建,以顯示誰創造了它爲user_id。同樣,一個項目需要記錄誰將其添加到列表中。

您需要將added_by_user_id列添加到您的items表中,以使其工作並跟蹤哪個用戶添加了該項目。

所以,你可以這樣做:

# To create a user and a list is easy! 
user = User.create(user_params) 
list = user.create_list(list_params) 

# but when adding an item, you need to know which user is adding it 
item = list.create_item({:added_by_user => current_user, :item_name => 'name', etc}) 

現在你可以使用找到用戶添加的所有項目:

all_user_items = user.items_added 

我沒有測試過這一點,這是一個有點複雜,所以我可能代碼中有1-2個錯誤,但通常這是可以模擬的一種方式。

+0

我喜歡這個,但我認爲OP想要保存哪個用戶添加了哪個項目。 – Kaeros 2013-02-28 01:53:52

+0

如果解決方案與您的解決方案類似,我會在User模型中添加以下行:'has_many:items,:through =>:lists',因此他可以直接執行:user.items。 – Kaeros 2013-02-28 01:54:47

+0

啊。我懂了。我的解決方案不會捕獲哪個用戶添加項目。讓我重溫一下。 – 2013-02-28 02:00:36