2012-04-15 61 views
1

这里很基本的问题,我需要在我的Category模型上编写一个before过滤器,以确保深度永远不会超过2个。这是迄今为止我所拥有的。如何在创建之前验证模型属性

应用程序/模型/ category.rb

before_create :check_depth 
    def check_depth 
    self.depth = 1 if depth > 2 
    end 

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

undefined method `>' for nil:NilClass 

所以,而不是设置深度为一个像我试图做我将如何发送错误呢?任何帮助获取当前函数的信息用途?在此先感谢

回答

5

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

你最简单的解决方案:

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

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

validates :depth, :inclusion => { :in => [0,1,2] }, :on => :create 

如果您的验证逻辑得到更复杂的,使用自定义验证程序:

# 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 

在使用此验证程序之前,编辑加载它,例如在初始化

# config/initializers/require_custom_validators.rb 
require File.join('validators/depth_validator') 

您需要重新启动您的轨道服务器更改后(和您在您的验证作出更改之后)。

现在,在您的产品类别型号:

validates :depth, :depth => true, :on => :create # the :on => :create is optional 

问题将在@category.save提高,所以你可以设置你的闪光的通知,像这样:

if @category.save 
    # success 
else 
    # set flash information 
end 
+0

哎呀,如果验证逻辑不太复杂,你甚至不需要自定义过滤器 - 将更新我的答案。 – emrass 2012-04-15 07:50:10

+0

谢谢你提供的所有信息,我用它提供了最直接的答案,并且确实使用了I18n,所以我将使用自定义验证器。非常感谢你的努力。 – ruevaughn 2012-04-15 21:39:56

+0

太棒了! I18n也将采用上述“最干净”的解决方案(选项2)。您只需在您的语言环境中为[en | de | ...]。errors.messages.inclusion进行翻译 - 或者在此处使用示例语言环境之一https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale作为基础。对于自定义验证器,而不是错误文本“mytext ...”放置一个符号,如:depth_not_in_range,并在[locale] .collaboration.errors.models.category.attributs.depth.depth_not_in_range中有翻译 – emrass 2012-04-15 22:09:35

1

您现在得到的错误是因为depth是零。我相信你想使用self.depth,如:

def check_depth 
    self.depth = 1 if self.depth > 2 
end 

我真的不知道你是什么意思发送一个错误...发送一个错误的位置呢?你在一个模型...

+0

我想我是想象发送一个错误,如:notice或something,但我想你可以在模型中不会这样做。这是我应该在控制器中进行的检查,而不是模型呢? – ruevaughn 2012-04-15 05:46:13

+0

我相信如此...但是,您可以设置对象的属性,如over_depth = true ... – Nobita 2012-04-15 05:48:04

+0

真的,我可以尝试,我会在我的控制器中创建一个before_filter,并有辅助方法来执行检查吗?或者在我的控制器中怎么做呢? – ruevaughn 2012-04-15 05:50:40

2

我会建议简单明了的方法:

# in your Comment.rb 
validates_inclusion_of :depth, in: 0..2, message: "should be in the range of 0..2" 
+0

这似乎适用于我以及。谢谢你的帮助 – ruevaughn 2012-04-15 21:41:08

相关问题