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

时间:2022-08-24 22:30:32

I have a model Listing that belongs_to :user. Alternatively, User has_many :listings. Each listing has a category field that classifies it (dogs, cats, etc). The User also has a boolean field called is_premium.

我有一个belongs_to:user的模型列表。或者,用户has_many:列表。每个列表都有一个分类字段(狗,猫等)。用户还有一个名为is_premium的布尔字段。

Here is how I am validating the category...

以下是我验证类别的方法......

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

Let's say I only want to allow premium users to be able to add tigers, lions, and rhinos. How would I go about this? Would it be best to do it in a before_save method?

假设我只想让高级用户能够添加老虎,狮子和犀牛。我怎么会这样呢?在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

Thanks in advance!

提前致谢!

3 个解决方案

#1


8  

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

#2


3  

If you want to add validation errors doing the before_save you could raise an exception then add the error in the controller like this:

如果你想在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

Then in your controller do something like:

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

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

Then in your /lib folder add a class like this:

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

module Exceptions
  class NotPremiumUser < StandardError; end
end

But in your case I think using the validate method is a better solution.

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

Cheers,

干杯,

#3


2  

You can use validates_exclusion_of:

您可以使用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

#1


8  

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

#2


3  

If you want to add validation errors doing the before_save you could raise an exception then add the error in the controller like this:

如果你想在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

Then in your controller do something like:

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

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

Then in your /lib folder add a class like this:

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

module Exceptions
  class NotPremiumUser < StandardError; end
end

But in your case I think using the validate method is a better solution.

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

Cheers,

干杯,

#3


2  

You can use validates_exclusion_of:

您可以使用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