如何使用验证器动态制作Rails的格式?

时间:2013-09-12 18:34:44

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

我正在尝试验证exchange_rate课程中Invoice的格式:

class Invoice < ActiveRecord::Base

  attr_accessible :currency, :exchange_rate

  validates :exchange_rate, :format => { :with => exchange_rate_format }

  private

  def exchange_rate_format
    if currency != user.preference.base_currency
      DECIMAL_REGEX
    else
      ANOTHER_REGEX
    end
  end

end

问题是:它根本不起作用。我想我需要在这里使用Proc?我从来没有真正弄清楚如何使用它。也许有人可以提供帮助。

非常感谢。

2 个答案:

答案 0 :(得分:1)

是的,您需要使用Proc或lambda,以便在运行时调用验证。

validates :exchange_rate, format: { with: ->(invoice) { invoice.exchange_rate_format } }
# Note, I used Ruby 1.9 hash and lambda syntax here.

要执行此操作,您需要将exchange_rate_format移出private方法列表,因为我们正在定义显式接收器(invoice)。如果您愿意,可以改为protected。或者你可以将条件放入lambda。

答案 1 :(得分:1)

一种方法是使用自定义验证器:

class Invoice < ActiveRecord::Base
  class ExchangeRateFormatValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      if !value =~ record.exchange_rate_format
        record.errors[attribute] << "your currency is weak sauce"
      end
    end  
  end

  validates :exchange_rate, exchange_rate_format: true

  # make public
  def exchange_rate_format
    if currency != user.preference.base_currency
      DECIMAL_REGEX
    else
     ANOTHER_REGEX
    end
  end
end