Rails 3验证包含何时使用find(如何proc或lambda)

Nic*_*s C 28 ruby validation activerecord ruby-on-rails

我有一个有CURRENCY和COUNTRY表的项目.有一个PRICE模型需要有效的货币和国家代码,所以我有以下验证:

validates :currency_code, :presence => true, :inclusion => { :in => Currency.all_codes }
validates :country_code, :presence => true, :inclusion => { :in => Country.all_codes }
Run Code Online (Sandbox Code Playgroud)

all_codes方法返回仅包含货币或国家/地区代码的数组.只要没有代码添加到表中,这样就可以正常工作.

你怎么写这个,以便Currency.all_codes的结果是Proc或lambda内?我尝试了Proc.new {Currency.all_codes} - 但是后来得到一个错误,该对象没有响应包含?

Mat*_*ins 64

只需使用proc,就像这样:

validates :currency_code,
          :presence => true,
          :inclusion => { :in => proc { Currency.all_codes } }
validates :country_code,
          :presence => true,
          :inclusion => { :in => proc { Country.all_codes } }
Run Code Online (Sandbox Code Playgroud)

值得注意的是,对于可能偶然发现这一点的人来说,proc也可以将记录作为参数访问.所以你可以这样做:

validates :currency_code,
          :presence => true,
          :inclusion => { :in => proc { |record| record.all_codes } }

def all_codes
  ['some', 'dynamic', 'result', 'based', 'upon', 'the', 'record']
end
Run Code Online (Sandbox Code Playgroud)


ctc*_*rry 5

注意:此答案适用于旧版本的 Rails,但对于 Rails 3.1 及更高版本,接受 procs。

它不能接受 Procs。您可以使用自定义验证方法来做同样的事情:

validate :currency_code_exists

def currency_code_exists
    errors.add(:base, "Currency code must exist") unless Currency.all_codes.include?(self.currency_code)
end
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在 rails >= 3.1 中,您可以使用 `lambda` 或 `proc`,就像下面未接受的答案一样。http://apidock.com/rails/v3.1.0/ActiveModel/Validations/HelperMethods/validates_inclusion_of (5认同)