Как удалить встроенный документ из Mongoid? - PullRequest
0 голосов
/ 03 октября 2011

У меня возникли некоторые проблемы при удалении моего документа с помощью Mongoid ... Код фактически удаляет галерею, но я получаю сообщение об ошибке браузера, которое выглядит следующим образом:

Mongoid :: Errors ::DocumentNotНайдено в / admin / galleries / delete / 4e897ce07df6d15a5e000001

Подозрительный код приведен ниже:

def self.removeGalleryFor(user_session_id, gallery_id)
  person = Person.any_in(session_ids: [user_session_id])
  return false if person.count != 1
  return false if person[0].userContent.nil?
  return false if person[0].userContent.galleries.empty?

  gallery = person[0].userContent.galleries.find(gallery_id) #ERROR is on this line
  gallery.delete if !gallery.nil?
end

Класс My Person встраивает один userContent, который включает в себя множество галерей.

Как ни странно, у меня есть пара тестов вокруг этого, которые работают нормально ...

Я действительно не уверен, что происходит - моя галерея, кажется, найдена в порядке, и даже удалена из Mongo.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 03 октября 2011

find выдает ошибку, если не может найти документ с заданным идентификатором.Вместо того, чтобы проверять наличие данной галереи и возвращать nil, если она не существует, вы напрямую спрашиваете mongodb, запрашивая удаление любой такой галереи.

def self.remove_gallery_for(user_session_id, gallery_id)
  user_session_id = BSON::ObjectId.from_string(user_session_id) if user_session_id.is_a?(String)
  gallery_id = BSON::ObjectId.from_string(gallery_id) if gallery_id.is_a?(String)

  # dropping to mongo collection object wrapped by mongoid, 
  # as I don't know how to do it using mongoid's convenience methods
  last_error = Person.collection.update(
      # only remove gallery for user matching user_session_id
      {"session_ids" => user_session_id}, 
      # remove gallery if there exists any
      {"$pull" => {:userContent.galleries => {:gallery_id => gallery_id}}},
      # [optional] check if successfully removed the gallery
      :safe => true
  )

  return last_error["err"].nil?
end

Таким образом, вы не загружаете Person, вы даже не получаете данные из monogdb на сервер приложений.Просто удалите галерею, если она существует.

Но вы должны предпочесть ответ @ fl00r, если вам нужно запустить обратные вызовы и переключиться на destroy вместо delete

0 голосов
/ 08 октября 2011

Спасибо Rubish за указание на решение, которое, по крайней мере, проходит мои тесты - по какой-то причине код fl00r не работает - похоже, что должен, но по какой-то причине не работает ...

Person.collection.update(
    {"session_ids" => user_session_id},
    {"$pull" => {'userContent.galleries' => {:_id => gallery_id}}},
    :safe => true
)

=> этот код пройдет мои тесты, но потом, когда он запустится в sinatra, он не будет работать ... так расстраивает!

разместил этот код с тестами на github https://github.com/LouisSayers/bugFixes/tree/master/mongoDelete

0 голосов
/ 03 октября 2011
def self.removeGalleryFor(user_session_id, gallery_id)
  # person = Person.where(session_ids: user_session_id).first
  person = Person.any_in(session_ids: [user_session_id])
  if person && person.userContent && person.userContent.galleries.any?
    gallery = person.userContent.galleries.where(id: gallery_id).first
    gallery.delete if gallery
  end
end

пс:

В Ruby обычно under_score используется вместо именования CamelCase

...