如何在创建之前验证模型属性

rue*_*ghn 1 ruby-on-rails

这里非常基本的问题,我需要在我的Category模型上编写一个过滤器,以确保深度永远不会超过2.这是我到目前为止所拥有的.

应用程序/模型/ category.rb

before_create :check_depth
  def check_depth
    self.depth = 1 if depth > 2
  end
Run Code Online (Sandbox Code Playgroud)

我需要它而不是将深度设置为1,只是为了返回错误消息,但我甚至无法让当前的设置工作,我得到错误

undefined method `>' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)

那么,而不是像我正在尝试做的那样将深度设置为一个而不是如何发送错误?任何帮助使当前功能为信息目的工作?提前致谢

emr*_*ass 5

有多种方法可以做到这一点.

最简单的解决方案:

def check_depth
  self.errors.add(:depth, "Issue with depth") if self.value > 2 # this does not support I18n
end
Run Code Online (Sandbox Code Playgroud)

最干净的是使用模型验证(在您的category.rb的顶部,只需添加):

validates :depth, :inclusion => { :in => [0,1,2] }, :on => :create
Run Code Online (Sandbox Code Playgroud)

如果验证逻辑变得更复杂,请使用自定义验证器:

# lib/validators/depth_validator.rb (you might need to create the directory)
class DepthValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors.add(attribute, "Issue with #{attribute}") if value > 2 # this could evene support I18n
  end
end
Run Code Online (Sandbox Code Playgroud)

在使用此验证器之前,您需要在初始化程序中加载它

# config/initializers/require_custom_validators.rb
require File.join('validators/depth_validator')
Run Code Online (Sandbox Code Playgroud)

您需要在更改后(以及在验证器中进行任何更改后)重新启动rails服务器.

现在在你的catagory模型中:

validates :depth, :depth => true, :on => :create # the :on => :create is optional
Run Code Online (Sandbox Code Playgroud)

这个问题将被提出,@category.save因此你可以像这样设置你的flash通知:

if @category.save
  # success
else
  # set flash information
end
Run Code Online (Sandbox Code Playgroud)