HABTM mongoid следующий / последователь - PullRequest
5 голосов
/ 20 декабря 2011

Монгоидные корабли с .push на habtm, который устанавливает отношения habtm в обоих направлениях. Несмотря на то, что удаление # удалит связанную запись, не существует документированного способа удаления только той связи, которую я видел. Есть ли лучший способ сделать это?

Есть ли лучший способ обеспечить уникальность?

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 Ответ

18 голосов
/ 21 декабря 2011

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

...