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

gbd*_*dev 5 ruby validation ruby-on-rails ruby-on-rails-3

我有一个模型Listingbelongs_to :user.或者,User has_many :listings.每个列表都有一个分类字段(,等).它User还有一个名为的布尔字段is_premium.

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

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

假设我只想让高级用户能够添加老虎,狮子犀牛.我该怎么做?用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
Run Code Online (Sandbox Code Playgroud)

提前致谢!

ush*_*sha 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
Run Code Online (Sandbox Code Playgroud)


Eri*_*ric 5

如果您想在 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
Run Code Online (Sandbox Code Playgroud)

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

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

然后在你的 /lib 文件夹中添加一个这样的类:

module Exceptions
  class NotPremiumUser < StandardError; end
end
Run Code Online (Sandbox Code Playgroud)

但是在您的情况下,我认为使用 validate 方法是更好的解决方案。

干杯,