我有以下结构:
class User < ActiveRecord::Base
end
class Item < ActiveRecord::Base
end
class Group < ActiveRecord::Base
end
User
可以创建(从而拥有)Group
Group
是Items
的列表以及可以访问这些项的Users
列表。
换句话说,用户有一个Items
列表,可以控制哪个Users
可以通过Group
成员资格查看这些项目。
我应该如何建立关系?
答案 0 :(得分:5)
好吧,你会遇到一些问题,因为你想在这里建立双重的多对多关系。 IE浏览器。群组拥有并属于许多项目,并且项目拥有并属于许多用户。
所以,我会以这种方式设置关系,假设您希望一个组能够拥有多个项目,并且项目可能属于多个组:
User has_many :groups
User has_and_belongs_to_many :items
User has_many :own_items, :class_name => 'Item'
Group belongs_to :user
Group has_and_belongs_to_many :items
Item has_and_belongs_to_many :groups
Item has_and_belongs_to_many :users
Item belongs_to :owner, :class_name => 'User'
您的迁移需要如下所示:
# Group
:user_id, :integer
# Item
:owner_id, :integer
# GroupsItems
:group_id
:item_id
#ItemsUsers
:item_id
:user_id
现在,您所看到的结构并不是宇宙中最干净的结构,但只要您对用户关联保持谨慎,它就会按照您的预期行事。
例如,要创建用户的项目:
@user = User.first
@user.own_items.create(...)
指定用户可以查看项目...
@item = Item.find(...) #or @user.own_items.find(...)
@item.users = [user1,user2,user3]
现在,这会设置您想要的关系,但您还必须编写自己的控制器/视图逻辑来限制访问,或使用像CanCan这样的库。
例如:
# View
- if @item.users.include?(current_user)
...show item...
# Items Controller:
def show
@item = Item.find(params[:id])
if @item.users.include?(current_user)
...continue...
else
redirect_to :back, :alert => 'You are not authorized to view this item.'
end
end
我希望这些例子能指出你正确的方向。您将有许多问题要处理与访问控制有关的问题,但尝试考虑它们并解决我能想到的每个问题都超出了这个问题的范围。
另外,请注意,这是我能想到的最简单的设置。如果关联中有更复杂的逻辑,那么您可能希望创建一个成熟的连接模型并使用has_many:通过关联而不是HABTM。
祝你好运!