Rails的多个父关系
问题描述:
三种型号:Rails的多个父关系
User
List
Item
一个User
可以有很多Lists
和List
可以有很多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)lists
由users
创建。
只有一个用户可以创建一个列表。许多用户可以在创建后将项目添加到列表中。
所以造型,这需要两个不同的关系
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个错误,但通常这是可以模拟的一种方式。
我喜欢这个,但我认为OP想要保存哪个用户添加了哪个项目。 – Kaeros 2013-02-28 01:53:52
如果解决方案与您的解决方案类似,我会在User模型中添加以下行:'has_many:items,:through =>:lists',因此他可以直接执行:user.items。 – Kaeros 2013-02-28 01:54:47
啊。我懂了。我的解决方案不会捕获哪个用户添加项目。让我重温一下。 – 2013-02-28 02:00:36