Mongoid中has_and_belongs_to_many使用


rails种建立多对多关联关系的时候,一般使用has_many通过第三张表来处理
如下:

# models/user_group_relation.rb
belongs_to :user
belongs_to :group

# models/user.rb
has_many :user_group_relations
has_many :categories, :through => :user_group_relations

# models/group.rb
has_many :user_group_relations
has_many :users, :through => :user_group_relations


也可以使用has_and_belongs_to_many来做,今天我们来看一下在
mongoid种应该如何做

假设我们有两个模型 用户和群组
1.一个组可以有多个管理员,多个成员
2.一个用户可是属于不同的组,也可以管理布同的组
这种场景就是典型的多对多关系


class User
  include Mongoid::Document

  field :name, type: String

  has_and_belongs_to_many
    :admin_of, inverse_of: :admins, class_name: 'Group'
  has_and_belongs_to_many
      :member_of, inverse_of: :members, class_name: 'Group'

end

#admin_of_ids: nil, member_of_ids: nil


class Group
  include Mongoid::Document

  field :name, type: String

  has_and_belongs_to_many
      :admins,  inverse_of: :admin_of, class_name: 'User'
  has_and_belongs_to_many
      :members, inverse_of: :member_of, class_name: 'User'

end


数据库中则多了两个对应的字段
User   #admin_of_ids: nil, member_of_ids: nil
Group  #admin_ids: nil, member_ids: nil

测试代码:

u1 = User.new(name: "peter foo", email: "[email protected]")
u1.save!

u2 = User.new(name: "bjorn bar", email: "[email protected]")
u2.save!

u3 = User.new(name: "john baz",  email: "[email protected]")
u3.save!

向第一组中添加管理员u1,添加成员u1,u2,u3
g1 = Group.new(name: "pbj common")
g1.admins << u1
g1.members.concat [u1,u2,u3]
g1.save!

向第二组中添加管理员u1,u2 添加成员u1,u2
g2 = Group.new(name: "pbj music")
g2.admins.concat [u1,u2]
g2.members.concat [u1,u2]
g2.save!


查看用户所管理的所有群组
u = User.first(conditions: {name: "peter foo"})
puts u.admin_of.map(&:name)
# => ["pbj masters", "pbj slaves"]

查看用户所属的所有群组
u = User.first(conditions: {name: "peter foo"})
puts u.member_of.map(&:name)


查看用户是否是管理员
u = User.first(conditions: {name: "peter foo"})
puts u.admin_of?


查看用户是否是某个组的管理员
u = User.first(conditions: {name: "peter foo"})
puts u.admin_of?(group)

这个方法没有提供,需要我们自己在model中添加
class User

  def admin_of? group
    self.admin_of.include?(group)
    # also works: group.admins.include?(self)
  end

end

对应mongoid版本较低的在模型中可以这样写
class User
  include Mongoid::Document

  field :name, type: String

  has_and_belongs_to_many
      :admin_of, inverse_of: :admins, class_name: 'Group'
  has_and_belongs_to_many
      :member_of, inverse_of: :members, class_name: 'Group'

end

class Group
  include Mongoid::Document

  field :name, type: String

  has_and_belongs_to_many
      :admins,  inverse_of: :admin_of, class_name: 'User'
  has_and_belongs_to_many
      :members, inverse_of: :member_of, class_name: 'User'

end

欢迎关注微信订阅号:ruby程序员


Mongoid中has_and_belongs_to_many使用
 资料:http://markentier.de/codecraft/2011/07/31/mongoid-multiple-many-to-many-relations/

你可能感兴趣的:(多对多,mongoid)