Rails中的简单自定义模型验证

时间:2011-01-20 21:41:49

标签: ruby-on-rails validation ruby-on-rails-3 model

我想做两个简单的自定义验证:

if project.end < project.start, raise an exception.
if project.start, set project.active to equal true

我的代码(可能非常不正常)不起作用:

class Project < ActiveRecord::Base
  before_save :check_data # now changed to before_validation

  def check_data
     if end < start
         errors.add(:base, 'Project end date must be after project start date.')
     end
     if start
         active = true
     end
  end

错误正在添加,但是但是我没有被带回错的消息 - 在用户方面似乎一切都很好。

此外,数据库中的字段active没有变化。


控制器代码:

@project = Project.find(params[:id])
if @project.update_attributes(params[:project])
    redirect_to home_url   
else
    flash[:error] = "There was an error saving your form."
    redirect_to edit_project_url
end

更新 - 如何更改模型中的字段?

我将上面的代码更改为before_validation,但是active字段仍未在数据库中进行更改。如何使上述模型代码有效?

答案:使用self.active

2 个答案:

答案 0 :(得分:5)

要使错误条件正常工作,请使用before_validation代替before_save

成功条件不正常,因为active赋值有局部变量,而不是模型属性。您必须在此处明确使用“自我”,例如self.active = true

答案 1 :(得分:4)

如果您正在验证,则应该使用before_validation。原因是,如果您有其他验证失败,您的check_data将永远不会运行,因此用户永远不会看到这些错误。这可能导致他们输入项目数据,获得验证错误,修复该错误,然后check_data运行并告诉他们另一个验证错误的情况。如果您使用before_validation,那么他们将立即看到所有错误。

我不知道这是否会实际修复您遇到的主动不保存的错误,但您注意到错误未显示在表单中的错误是由于您使用了redirect_to edit_project_url - 您应该使用

render :edit

来自您的更新操作和

render :new

来自您的创建操作。 errors实际上是@project对象的一部分,因此当您将(而不是渲染)重定向到新操作时,会创建一个新对象。重定向到编辑页面时,将从数据库加载现有对象。这就是你的错误数组正在消失的方式。如果渲染而不是重定向,则您的错误将保留在对象上并显示在视图中(假设您已正确设置了所有内容)。

希望有所帮助,祝你好运找出活跃的国家问题!