好吧,你会遇到一些问题,因为你想要一个双多对多的关系。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 :through 关联而不是 HABTM。
祝你好运!