使用before_save回调或自定义验证器添加验证错误?

时间:2013-10-23 14:32:50

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

我有Listing的模型belongs_to :user。或者,User has_many :listings。每个商家信息都有一个类别字段,可以对其进行分类( dogs cats 等)。 User还有一个名为is_premium的布尔字段。

以下是我如何验证类别......

validates_format_of :category,
                    :with => /(dogs|cats|birds|tigers|lions|rhinos)/,
                    :message => 'is incorrect'

假设我只想让高级用户能够添加老虎狮子会 rhinos 。我该怎么做?最好是用before_save方法吗?

before_save :premium_check

def premium_check
  # Some type of logic here to see if category is tiger, lion, or rhino.
  # If it is, then check if the user is premium. If it's not, it doesn't matter.
  # If user isn't premium then add an error message.
end

提前致谢!

3 个答案:

答案 0 :(得分:9)

class Listing < ActiveRecord::Base    
  validate :premium_category

  private

  def premium_category
    if !user.is_premium && %w(tigers lions rhinos).include?(category))
      errors.add(:category, "not valid for non premium users")
    end
  end
end

答案 1 :(得分:3)

如果你想在before_save中添加验证错误,你可能会引发一个异常,然后像这样在控制器中添加错误:

class Listing < ActiveRecord::Base    
  before_save :premium_category

  private

  def premium_category
    if !user.is_premium && %w(tigers lions rhinos).include?(category))
      raise Exceptions::NotPremiumUser, "not valid for non premium users"
    end
  end
end

然后在您的控制器中执行以下操作:

begin 
    @listing.update(listing_params)
    respond_with(@listing)
rescue Exceptions::NotPremiumUser => e
      @listing.errors.add(:base, e.message)
      respond_with(@listing)    
end

然后在/ lib文件夹中添加如下类:

module Exceptions
  class NotPremiumUser < StandardError; end
end

但在你的情况下,我认为使用验证方法是一个更好的解决方案。

干杯,

答案 2 :(得分:2)

您可以使用validates_exclusion_of

validates :category, :exclusion => {
  :in => ['list', 'of', 'invalid'],
  :message => 'must not be premium category',
  :unless => :user_is_premium?
}

protected

def user_is_premium?
  self.user.premium?
end