Следующий код работал для меня нормально (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 (прокрутите вниз до «ЗАВИСИМОЕ ПОВЕДЕНИЕ»).