Rails3 / Mongoid: отношение «многие ко многим» и операция удаления - PullRequest
1 голос
/ 03 февраля 2012

У меня есть следующая модель:

class User
  include Mongoid::Document
  include Mongoid::Timestamps

  has_and_belongs_to_many :challenged, class_name: "Event", inverse_of: "challengers"

  def challenge!(event)
    self.challenged << event
    self.save!
  end

  def unchallenge!(event)
    self.challenged.where(_id: event.id).destroy_all
    self.save!
  end
end

class Event
  include Mongoid::Document
  include Mongoid::Timestamps

  has_and_belongs_to_many :challengers, class_name: "User", inverse_of: "challenged"
end

Задача! метод работает отлично, но без проблем! один не делает. Если я проверю это с помощью следующего кода:

require 'spec_helper'

describe User do
  before(:each) do
    @user = User.create!
    @event = Event.create!
  end

  it "should unchallenge an event" do
    @user.challenge!(@event)
    @user.unchallenge!(@event)
    @user.challenged.should_not include(@event)
  end

end

Тест не пройден; так что похоже, что операция удаления не работает.

Журналы приложений:

MONGODB test_mongo_test['users'].insert([{"challenged_ids"=>[], "_id"=>BSON::ObjectId('4f2d13fdbd028603f7000001')}])
MONGODB test_mongo_test['system.namespaces'].find({})
MONGODB test_mongo_test['events'].insert([{"challenger_ids"=>[], "_id"=>BSON::ObjectId('4f2d13fdbd028603f7000002')}])
MONGODB test_mongo_test['events'].update({"_id"=>BSON::ObjectId('4f2d13fdbd028603f7000002')}, {"$addToSet"=>{"challenger_ids"=>{"$each"=>[BSON::ObjectId('4f2d13fdbd028603f7000001')]}}})
MONGODB test_mongo_test['users'].update({"_id"=>BSON::ObjectId('4f2d13fdbd028603f7000001')}, {"$pushAll"=>{"challenged_ids"=>[BSON::ObjectId('4f2d13fdbd028603f7000002')]}})
MONGODB test_mongo_test['$cmd'].find({"count"=>"events", "query"=>{"$and"=>[{:_id=>{"$in"=>[BSON::ObjectId('4f2d13fdbd028603f7000002')]}}, {:_id=>BSON::ObjectId('4f2d13fdbd028603f7000002')}]}, "fields"=>nil}).limit(-1)
MONGODB test_mongo_test['events'].remove({"$and"=>[{:_id=>{"$in"=>[BSON::ObjectId('4f2d13fdbd028603f7000002')]}}, {:_id=>BSON::ObjectId('4f2d13fdbd028603f7000002')}]})
MONGODB test_mongo_test['events'].find({:_id=>{"$in"=>[BSON::ObjectId('4f2d13fdbd028603f7000002')]}})
MONGODB test_mongo_test['events'].find({:_id=>{"$in"=>[BSON::ObjectId('4f2d13fdbd028603f7000002')]}})

1 Ответ

1 голос
/ 03 февраля 2012

Проверьте журнал приложения

Если я прав, self.challenged возвращает критерии события, а не критерии пользователя, поэтому исправьте:

self.challenged.where(_id: event.id).destroy_all

Обновление

Я написал такой же тест, как и вы (только разные названия моделей):

# announcement_list.rb
def challenge!(announce)
  self.announcements << announce
  self.save!
end

def unchallenge!(announce)
  self.announcements.where( _id: announce.id ).destroy_all
  self.save!
end

#anouncement_list_spec.rb
context 'stackoverflow#9132596' do
  let!( :announcement_list ) { Factory( :announcement_list ) }
  let!( :announcement ) { Factory( :announcement ) }
  it 'kick announcement out of list on unchallenge! method call' do
    announcement_list.challenge!( announcement )
    announcement_list.unchallenge!( announcement )
    announcement_list.announcements.should_not include( announcement )
  end
end

Таким образом, мои тесты не пройдены.Затем я меняю:

def unchallenge!(announce)
  self.announcements.destroy_all( conditions: { _id: announce.id })
  self.save!
end

Да, немного хитро, и определенно должен быть помещен в трекер mongoid.Надеюсь, это поможет вам.

...