2013-09-20 3 views
0

У меня есть следующий класс:Mongoid не отменяет существующие документы через .create

class Magazine 
    include Mongoid::Document 

    field :name 
    field :count 
    field :_id, default: -> { name } 

Я создавать новые документы этого типа через Magazine.create!(name: "Yolo", count: 2). Это прекрасно работает. Теперь, когда я хочу, чтобы обновить этот документ в MongoDB, потому что граф изменился, я думал, что это будет работать:

Magazine.create!(name: "Yolo", count: 42) 

Название карты с тем же идентификатором и поэтому документ получает перекрываться. Хотя кажется, что операция прошла успешно, в MongoDB документ не обновлялся.

Вместо этого я должен сделать:

Magazine.where(name: "Yolo").first.update_attributes!(count: 42) 

Который работает, но может кто-нибудь объяснить, почему мой первый подход не работает, и если мой второй подход является распространенным способом обновить документы через Mongoid?

ответ

2

Проблема была воспроизведена на моей машине, и я нашел решение.

Model#create! вызывает ошибку, если ошибкапроверка происходит не ошибка базы данных, в соответствии с document или the code on github. Так что это не решение вашего вопроса.

Runtime Persistence Optionwith(safe: true) может сообщить Mongoid, чтобы поднять ошибки базы данных, указанные в the driver Moped. В твоем случае. Ошибка выглядит следующим образом:

1.9.3-p0 :009 > Magazine.with(safe: true).create!(name: "Yolo", count: 42) 
Moped::Errors::OperationFailure: The operation: #<Moped::Protocol::Command 
    @length=71 
    @request_id=7 
    @response_to=0 
    @op_code=2004 
    @flags=[] 
    @full_collection_name="mongoid.$cmd" 
    @skip=0 
    @limit=-1 
    @selector={:getlasterror=>1, :safe=>true} 
    @fields=nil> 
failed with error 11000: "E11000 duplicate key error index: mongoid.magazines.$_id_ dup key: { : \"Yolo\" }" 

Кроме того, безопасный режим может быть установлен по умолчанию в конфигурации YAML, как описано в document.

Возможно, вы бы хотели найти журнал с кодом Magazine.find("Yolo"), чтобы использовать индекс _id, созданный MongoDB по умолчанию. Даже если _id совпадает с name, Mongoid недостаточно умен, чтобы использовать _id, чтобы найти документ.

1

Я думаю, что я немного удивлен вашим вторым призывом создать! не вызывает ошибки.

Попробуйте использовать поисковый метод, связанный с обновлением, которое является довольно распространенным один вкладыш для обновления атрибутов:

Magazine.find('Yolo').update_attributes(count: 42) 
+0

'find' принимает идентификатор в качестве параметра, вы, вероятно, имеете в виду' find_by (name: 'Yolo') '. – toro2k

+2

Я знаю. «Yolo» - это идентификатор, а также имя. –

Смежные вопросы