Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 492
Nicholas C Avatar asked Feb 17 '11 21:02

Nicholas C


People also ask

How does validation work in Rails?

Rails built-in Validation MethodsValidates whether associated objects are all valid themselves. Work with any kind of association. It validates whether a user has entered matching information like password or email in second entry field. Validates each attribute against a block.

What is the difference between validate and validates in rails?

So remember folks, validates is for Rails validators (and custom validator classes ending with Validator if that's what you're into), and validate is for your custom validator methods.

How do I bypass validation?

A very common way to skip validation is by keeping the value for immediate attribute as 'true' for the UIComponents. Immediate attribute allow processing of components to move up to the Apply Request Values phase of the lifecycle. scenario: While canceling a specific action, system should not perform the validation.


1 Answers

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 
like image 82
Matt Huggins Avatar answered Sep 24 '22 08:09

Matt Huggins