在更新期间针对原始记录运行的Rails验证

时间:2010-02-13 12:35:50

标签: ruby-on-rails validation activerecord

我试图找出功能测试中发生的事情与我的开发环境中发生的事情之间的不一致。我有一个自定义验证方法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 个答案:

答案 0 :(得分:2)

在您的测试中,不应该有:entry的引用,因为这是您在控制器params[:entry]中寻找的内容?