简体   繁体   中英

Rails 3 validates inclusion of when using a find (how to proc or lambda)

I've got a project where there is a CURRENCY and COUNTRY table. There's a PRICE model that requires a valid currency and country code, so I have the following validation:

validates :currency_code, :presence => true, :inclusion => { :in => Currency.all_codes }
validates :country_code, :presence => true, :inclusion => { :in => Country.all_codes }

The all_codes method returns an array of just the currency or country codes. This works fine so long as no codes are added to the table.

How would you write this so that the result of the Currency.all_codes was either a Proc or inside a lambda? I tried Proc.new { Currency.all_codes } -- but then get an error that the object doesn't respond to include?

Just use a proc, like so:

validates :currency_code,
          :presence => true,
          :inclusion => { :in => proc { Currency.all_codes } }
validates :country_code,
          :presence => true,
          :inclusion => { :in => proc { Country.all_codes } }

It's worth noting for anyone else who may stumble across this that the proc also has the record accessible as a parameter. So you can do something like this:

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

def all_codes
  ['some', 'dynamic', 'result', 'based', 'upon', 'the', 'record']
end

Note: This answer is true for old versions of Rails, but for Rails 3.1 and above, procs are accepted.

It must not accept Procs. You can use a custom validation method to do the same thing:

validate :currency_code_exists

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM