Я пытаюсь выяснить несоответствие между тем, что происходит в функциональном тесте, и тем, что происходит в моей среде разработки. У меня есть пользовательский метод проверки unique_entry
, который по сути является специализированной версией validates_uniqueness_of
. Это выглядит так:
def unique_entry
matched_entry = Entry.first(:conditions => ['LOWER(field_one) = LOWER(?) AND LOWER(field_two) = LOWER(?)', self.field_one, self.field_two])
errors.add_to_base('Duplicate detected') if matched_entry && (matched_entry.id != self.id)
end
Действие обновления в контроллере очень простое:
def update
if @entry.update_attributes(params[:entry])
flash.now[:success] = 'Success'
render :action => 'show'
else
flash.now[:error] = 'Error'
render :action => 'edit'
end
end
Это прекрасно работает, когда я создаю новую запись. Однако, когда я обновляю запись, я получаю противоречивое поведение. Если я тестирую его из браузера в моей среде разработки, он корректно отображает действие edit
с сообщением об ошибке, но в моем функциональном тесте оно принимает обновление как успешное. Вот тест:
test "should not update entry and should render edit view if invalid update" do
put :update, { :id => 1, :field_one => 'new_value', :field_two => 'new_value' } # 'new values' are the same as another existing record to trigger the duplication check
assert_template :edit
assert_not_nil flash[:error]
end
Я посмотрел журнал испытаний и обнаружил, что значения, используемые unique_entry
, являются исходными значениями записи, а не значениями, которые она должна пытаться обновить. То есть первая строка unique_entry
генерирует SQL-запрос, подобный следующему:
SELECT * FROM "entries" WHERE (LOWER(field_one) = LOWER('original_value_of_field_one') AND LOWER(field_two) = LOWER('original_value_of_field_two')) LIMIT 1
Что мне здесь не хватает? Почему мои проверки выполняются для исходной записи, а не для новых значений только в тестовой среде?