HABTM mongoid追随者/追随者

时间:2011-12-20 19:25:57

标签: ruby-on-rails mongoid has-and-belongs-to-many

Mongoid在一个habtm上运行.push,它在两个方向上建立了一个habtm关系。虽然删除将#delete一个相关的记录,但没有记录的方法只删除我见过的关系。有没有更好的方法呢?

有没有更好的方法来确保独特性?

has_and_belongs_to_many :following, {class_name: 'User', inverse_of: :followers, inverse_class_name: 'User'}
  has_and_belongs_to_many :followers, {class_name: 'User', inverse_of: :following, inverse_class_name: 'User'}

  def follow!(user)
    self.following.push(user) # this pushes the inverse as well
    self.following_ids.uniq!
    self.save!
    user.follower_ids.uniq!
    user.save!
  end

  def unfollow!(user)
    self.following.delete(user.id)
    self.save!
    user.followers.delete(self.id)
    user.save!
  end

1 个答案:

答案 0 :(得分:18)

以下代码对我来说很好(mongoid 2.3.x):

class User
  include Mongoid::Document

  field :name, type: String

  has_and_belongs_to_many :following, class_name: 'User', inverse_of: :followers, autosave: true
  has_and_belongs_to_many :followers, class_name: 'User', inverse_of: :following

  def follow!(user)
    if self.id != user.id && !self.following.include?(user)
      self.following << user
    end
  end

  def unfollow!(user)
    self.following.delete(user)
  end
end

没有inverse_class_name,没有保存电话,没有特殊处理,但排除了自我跟踪。

原因是,如果没有添加到关系语句中,mongoid会自动使用dependent: nullify。使用autosave: true可以保存关系更新(并且只需要跟随,因为我们不会直接更改关注者)。如果没有自动保存选项,则需要在方法中添加一个保存调用,因为mongoid不会自动保存关系更新(自2.0.0.x起)。

我把if子句作为块,所以你可以通过异常处理(else raise FooException)来改变它。

.delete(user)没问题,在mongoid文档中也有提及:http://mongoid.org/docs/relations/referenced/n-n.html(向下滚动到“依赖行为”)。