Rails的多个父关系

问题描述:

三种型号: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! 

所以,我缺少什么?我的关系错了吗(很有可能)?告诉我! :)

好像有可能是项目和用户之间不同的关系:由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