Проверки Rails, работающие с исходной записью во время обновления - PullRequest
0 голосов
/ 13 февраля 2010

Я пытаюсь выяснить несоответствие между тем, что происходит в функциональном тесте, и тем, что происходит в моей среде разработки. У меня есть пользовательский метод проверки 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

Что мне здесь не хватает? Почему мои проверки выполняются для исходной записи, а не для новых значений только в тестовой среде?

1 Ответ

2 голосов
/ 13 февраля 2010

В вашем тесте не должно быть какой-либо ссылки на :entry, так как это то, что вы ищете в контроллере params[:entry]?

...