ActiveRecord validation reflection.

In my model class I have:   class X < ActiveRecord:Base     validates_length_of :login, :within => 3..40   end

In my view file I do:     <label for="login">Login (3..40 characters)

Is there a way to query this length information? Hence, having hard-coded "3..40" in the view is NOT good, as the length limit may change from model definition. I rather do something like:     <label for="login">Login (<%= find_the_frigging_length_from_model_X %> characters)

thx, Ray

You could set the minumum and/or maximum via a class attribute. Like I just did in the console.

>> class Joe >> @@val = {:pass_length => {:min => 3, :max => 40}} >> cattr_accessor :val >> end => [:val] >> Joe.val => {:pass_length=>{:min=>3, :max=>40}} >> Joe.val[:pass_length][:min] => 3 >>

Then do your validations also using the class attribute validates_length_of :login, :within => val[:login][:min]..val[:login][:max]

Voila! Jason

rexaler wrote:

Hi

To cope with similar issues some time ago I released this project

http://simpledesc.rubyforge.org/

Maybe you can find it of some help. It provides a facility to store and query extra data about your classes / models

The current release is working but the code is not brilliant. In subversion there's already a newer version which I may release as a gem in the next few weeks.

Paolo

You could set the minumum and/or maximum via a class attribute. Like I just did in the console.

>> class Joe >> @@val = {:pass_length => {:min => 3, :max => 40}} >> cattr_accessor :val >> end => [:val] >> Joe.val => {:pass_length=>{:min=>3, :max=>40}} >> Joe.val[:pass_length][:min] => 3 >>

Then do your validations also using the class attribute validates_length_of :login, :within => val[:login][:min]..val[:login][:max]

Voila! Jason

rexaler wrote:

> In my model class I have: > class X < ActiveRecord:Base > validates_length_of :login, :within => 3..40 > end

> In my view file I do: > <label for="login">Login (3..40 characters)

> Is there a way to query this length information? > Hence, having hard-coded "3..40" in the view is NOT good, as the length > limit may change from model definition. I rather do something like: > <label for="login">Login (<%= find_the_frigging_length_from_model_X > %> characters)

Class attribute is one option, class constant is another..

class X < ActiveRecord::Base   MIN_PASS = 3   MAX_PASS = 40   validates_length_of :login, :within => MIN_PASS..MAX_PASS end

and in the view

<label for="login">Login (<%= "#{X::MIN_PASS}-#{X::MAX_PASS}" %> characters)</label>

-r

http://www.agilewebdevelopment.com/plugins/validation_reflection

See also

http://schuerig.de/michael/blog/?p=8

HTH, Michael

Thanks guys. It's really helpful to see different ways of resolving this problem. For now I'm doing this (based on the validation_reflection plugin from Michael's post):

    refls = X.reflect_on_validations_for("login")     ref = refls.collect{ |ref| ref.macro == :validates_length_of ? ref : nil }.compact.first     ref.options[:within].to_s

Not sure if this is the best way (other suggestions?), but gets what I need. I will try to take the next step to make this a method call for any given ActiveRecord class, attribute, validation type and option.

thx, Ray

And this is what I have now:   def get_validation_option(clazz, method_name, validation, option)     refls = clazz.reflect_on_validations_for(method_name)     ref = refls.collect{ |ref| ref.macro == validation ? ref : nil }.compact.first     ref.options[option].to_s   end

Tested in a controller (or view):    logger.debug(get_validation_option(Person, "login", :validates_length_of, :within))

Ray

Consider this alternative

  def get_validation_option(clazz, method_name, validation,       option, default = nil)     refl = clazz.reflect_on_validations_for(method_name).find { |r|       r.macro == validation     }     if refl       (refl.options[option] || default).to_s     else       default     end   end

Michael