2013-03-07 51 views
1

我使用Rails 3.2.11的Mac OS X山狮,红宝石1.9.3before_validation在轨失败

所以我有这样一段代码:

class Points < ActiveRecord::Base 
validates :id, :presence => true 

before_create :validate_points 

def validate_points 
    if self.amount < 0 
    Rails.logger.error "Invalid amount of points" 
    else 
    save! 
    end 
end 

我想限制用户插入负值。但由于某种原因,validate_points方法不起作用。我做错了什么?谢谢。

回答

3

你应该Rails的使用提供了validates_numericality_of方法

validates :amount, numericality: { greater_than_or_equal_to: 0 } 

UPDATE:问题在你的代码

有你的代码中的几个问题。

  1. 您正在使用before_create,它在记录保存到数据库之前被调用。以这种方式防止数据库提交的唯一方法是在回调中返回false,但这不是一种好的做法。
  2. validate_points调用save!但被称为在before_create回调,所以你是在救你的记录2X UPDATE:由rxing指出,这将导致一个无限循环,而不是仅仅2保存到数据库中

,如果你不想使用内置的验证,请尝试以下

validate :validates_amount_points 

def validates_amount_points 
    errors.add_to :amount, 'must be greater than or equal to 0' if amount < 0 
end 
1

您需要使用“有效性”,而不是before_create钩。顺便说一下,你的before_create也是不正确的。从“save!”开始,它会引发SystemStackError:堆栈层次过深。会递减before_create。

+1

这是不正确的。 'before_create'只会触发一次。如果是'before_save',那么我会同意你的看法。 – jvnill 2013-03-07 07:32:55

+1

当您保存一个new_record时,before_create将被递归调用,因为它没有机会成为一个“现有记录”。 这就是为什么它会在before_create的死循环中。 – rxing 2013-03-07 07:48:35

+0

嗯有趣。现在我更多地思考它,你是对的。它永远不会超过创造记录的地步。很好的接收! – jvnill 2013-03-07 07:50:43