Rails模型关系,有很多属于很多?

ESo*_*oft 2 model ruby-on-rails ruby-on-rails-3

我有以下结构:

class User < ActiveRecord::Base
end

class Item < ActiveRecord::Base
end

class Group < ActiveRecord::Base
end
Run Code Online (Sandbox Code Playgroud)

A User可以创建(从而拥有)a Group.
A Group是可以访问这些项目ItemsUsers人员列表和列表.换句话说,用户具有可以通过成员资格查看这些项目的列表Items并且可以控制哪些Users项目Group.

我该如何建立这种关系?

And*_*rew 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'
Run Code Online (Sandbox Code Playgroud)

您的迁移需要如下所示:

# Group
:user_id, :integer

# Item
:owner_id, :integer

# GroupsItems
:group_id
:item_id

#ItemsUsers
:item_id
:user_id
Run Code Online (Sandbox Code Playgroud)

现在,您所看到的结构并不是宇宙中最干净的结构,但只要您对用户关联保持谨慎,它就会按照您的预期运行.

例如,要创建用户的项目:

@user = User.first
@user.own_items.create(...)
Run Code Online (Sandbox Code Playgroud)

为用户分配能够查看项目...

@item = Item.find(...) #or @user.own_items.find(...)
@item.users = [user1,user2,user3]
Run Code Online (Sandbox Code Playgroud)

现在,这将建立您想要的关系,但您还必须编写自己的控制器/视图逻辑来限制访问,或使用像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
Run Code Online (Sandbox Code Playgroud)

我希望这些例子能指出你正确的方向.您将遇到许多与访问控制相关的问题,但尝试考虑它们并解决我能想到的每个问题都超出了这个问题的范围.

另请注意,这是我能想到的最简单的设置.如果关联中有更复杂的逻辑,那么您可能希望创建一个完整的连接模型并使用has_many:通过关联而不是HABTM.

祝好运!