У меня есть несколько вложенных моделей, которые требуют немного больше, чем стандартная логика accepts_nested_attributes_for
.Вместо того, чтобы автоматически создавать или обновлять дочерние записи на основе ключа идентификатора, в этом случае дочерние записи должны уже существовать и иметь определенные другие условия, или возникает ошибка.
Так что, как часть этого, у меня есть родительский элементМодель итерирует по заданным дочерним атрибутам и вызывает #update_attributes для соответствующих дочерних записей.
Мой вопрос заключается в том, как смоделировать #update_attributes
в спецификациях для родительской модели.Я хочу проверить, что дочерние записи, идентифицируемые данными атрибутами, на самом деле являются теми, которые получают #update_attributes
Мой первый подход состоял в том, чтобы попробовать mock_model, что-товот так (не используя фактические названия моделей, а просто «субъект» и «дети» для ясности):
before :each do
subject.children = mock_model(Child), mock_model(Child), mock_model(Child)
subject.save!
@expected = subject.children[1]
@input = {:child_id => @expected.id, :value => 'something'}
end
it 'should call #update_attributes on the child with given attributes' do
@expected.should_receive(:update_attributes).
with({:value => 'something'})
subject.merge_children_attributes(@input)
end
Однако вы не можете на самом деле сохранять макеты моделей.И вы не можете использовать модели заглушки по той же причине.И мне нужны постоянные записи, так как я использую children.find()
или children.all()
в реализации.(если я не высмеиваю ассоциацию children
, которая кажется неправильной, учитывая, что это метод субъекта).
Итак, я пошел к светильникам.
fixtures :children
before :each do
subject.children = children(:one), children(:two), children(:three)
subject.save!
@expected = subject.children[1]
@input = {:child_id => @expected.id, :value => 'something'}
end
it 'should call #update_attributes on the child with given attributes' do
@expected.should_receive(:update_attributes).
with({:value => 'something'})
subject.merge_children_attributes(@input)
end
Проблема здесь в том, что ожидаемая совпавшая запись (@expected
) никогда не получает :update_attributes
- ни с чем.
При большом количестве puts
причина этого в том, что когда реализация вызывает children.find()
, она возвращает другой экземпляр , чем @expected = subject.children[1]
в спецификации.Хотя атрибут: id такой же.ActiveRecord не является идентификационной картой ...
Так как мне написать эту спецификацию для передачи?
ОБНОВЛЕНИЕ
Я подтвердил, просматривая журнал, чтоправильная запись фактически обновляется.Поэтому досадно, что я не могу насмехаться над :update_attributes
, потому что идентичность объекта не поддерживается между find
с.