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
答案 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(向下滚动到“依赖行为”)。