Hello people, I''d like to detect whether an attribute of a model has vaildates_presence_of applied to it so I can automatically apply a mandatory (*) to the field...it doesn''t look easy...any ideas? Cheers, -- Dan Webb http://www.danwebb.net
Dan Webb wrote the following on 27.07.2006 02:28 :> Hello people, > > I''d like to detect whether an attribute of a model has > vaildates_presence_of applied to it so I can automatically apply a > mandatory (*) to the field...it doesn''t look easy...any ideas? > > Cheers, >My first reflex would be to override ActiveRecord::Base#validates_presence_of to populate a Hash in the model to keep track of which attribute is validated or not : module ActiveRecord class Base alias_method :no_trancking_validates_presence_of, :validates_presence_of def validates_presence_of(*attr_names) @attr_presence_validated = Hash.new unless @attr_presence_validated attr_names.each {|a| @attr_presence_validated[a]=true} no_tracking_validates_presence_of(*attr_names) end def attr_presence_validated @attr_presence_validated end end end Put this in a lib and include it in environment.rb Then in your view you can test with: your_model.attr_presence_validated.include?(attr_name) Lionel.
> Then in your view you can test with: > your_model.attr_presence_validated.include?(attr_name) > > Lionel.Yeah, I like it. Nice and simple. Thanks Lionel. -- Dan Webb http://www.danwebb.net
On Thursday 27 July 2006 02:28, Dan Webb wrote:> I''d like to detect whether an attribute of a model has > vaildates_presence_of applied to it so I can automatically apply a > mandatory (*) to the field...it doesn''t look easy...any ideas?Dan, below is some I''ve been using with a somewhat monkeypatched version of Rails pre-1.0. I''ve adapted it a bit so that it works with Rails 1.1.4, but haven''t done any testing. All the code is under LGPL. When time permits, I hope to make this stuff into a plugin. Michael [Sorry for the mangled line breaks] require ''active_record/reflection'' # Based on code by Sebastian Kanthak # See http://dev.rubyonrails.org/ticket/861 module BoilerPlate module RailsExtensions # :nodoc: module ValidationReflection # :nodoc: VALIDATIONS = %w( validates_acceptance_of validates_associated validates_confirmation_of validates_exclusion_of validates_format_of validates_inclusion_of validates_length_of validates_numericality_of validates_presence_of validates_uniqueness_of ).freeze def self.included(base) base.extend(ClassMethods) for validation_type in VALIDATIONS base.module_eval <<-"end_eval" class << self alias_method :#{validation_type}_without_reflection, :#{validation_type} def #{validation_type}_with_reflection(*attr_names) #{validation_type}_without_reflection(*attr_names) configuration = attr_names.last.is_a?(Hash) ? attr_names.pop : nil for attr_name in attr_names write_inheritable_array "validations", [ ActiveRecord::Reflection::MacroReflection.new(:#{validation_type}, attr_name, configuration, self) ] end end alias_method :#{validation_type}, :#{validation_type}_with_reflection end end_eval end end module ClassMethods # Returns an array of MacroReflection objects for all validations in the class def reflect_on_all_validations read_inheritable_attribute("validations") || [] end # Returns an array of MacroReflection objects for all validations defined for the field +attr_name+ (expects a symbol) def reflect_on_validations_for(attr_name) reflect_on_all_validations.find_all do |reflection| reflection.name == attr_name end end end end end end require ''active_record/validations'' module BoilerPlate # :nodoc: module RailsExtensions # :nodoc: module Validations # :nodoc: def self.included(base) base.extend(ClassMethods) end module ClassMethods # Validates the presence of attributes and associations # where, according to database metadata, the corresponding # column must not be +null+. # Options: # <tt>:exclude</tt> - properties (as symbols) to be excluded def validates_presence_of_mandatory_content_columns(options = {}) columns = mandatory_content_columns - Array(options[:exclude]) validates_presence_of(*columns) end # Validates the lengths of string attributes against the # limit defined by their database type. # +Nil+ values are explicitly allowed as they are checked # with +validates_presence_of+ # Options: # <tt>:exclude</tt> - attributes (as symbols) to be excluded def validates_lengths_of_string_attributes(options = {}) columns = content_columns - Array(options[:exclude]) columns.select { |col| col.type == :string and col.limit }.each do |col| validates_length_of(col.name.to_sym, :maximum => col.limit, :allow_nil => true) end end # Validates all associated objects. # +Nil+ values are explicitly allowed as they are checked # with +validates_presence_of+ # Options: # <tt>:exclude</tt> - associations (as symbols) to be excluded def validates_all_associated(options = {}) associations = reflect_on_all_associations.map { |a| a.name } - Array(options[:exclude]) validates_associated(*associations) end protected def mandatory_content_columns return @mandatory_content_columns if @mandatory_content_columns @mandatory_content_columns = [] content_columns.find_all { |col| !col.null }.each do |col| @mandatory_content_columns << col.name end @mandatory_content_columns end end end end end require ''cgi'' require ''action_view/helpers/form_helper'' module BoilerPlate # :nodoc: module RailsExtensions # :nodoc: module InstanceTagValidationsSupport def self.included(instance_tag) instance_tag.class_eval do alias_method :tag_without_validation, :tag alias_method :content_tag_without_validation, :content_tag alias_method :tag, :tag_with_validations alias_method :content_tag, :content_tag_with_validations end end def tag_with_validations(name, options = {}) options = merge_validations!(options) tag_without_validation(name, options) end def content_tag_with_validations(name, content, options = {}) options = merge_validations!(options) content_tag_without_validation(name, content, options) end private def merge_validations!(options) if options.delete(''ignore_validations'') return options end unless method_name && object.class.respond_to? (:reflect_on_validations_for) return options end validations = object.class.reflect_on_validations_for(method_name.without_suffix(''_id'').to_sym) validations.each do |validation| case validation.macro when :validates_presence_of add_class_name!(options, ''mandatory'') when :validates_length_of if minlength = validation_minlength(validation.options) add_class_name!(options, encode_validation(''minlength'', minlength)) end if maxlength = validation_maxlength(validation.options) add_class_name!(options, encode_validation(''maxlength'', maxlength)) end when :validates_numericality_of add_class_name!(options, ''numeric'') when :validates_inclusion_of values = validation.options[:in] if values.kind_of?(Range) ### FIXME RAILS_DEFAULT_LOGGER.debug("Only inclusion validations for inclusive Ranges are supported") if values.exclude_end? add_class_name!(options, encode_validation(''range'', values.begin, values.end)) else ### FIXME RAILS_DEFAULT_LOGGER.debug("Only inclusion validations for inclusive Ranges are supported") end when :validates_format_of add_class_name!(options, encode_validation(''format'', validation.options[:with])) end end options end def add_class_name!(options, class_name) return options unless class_name options.stringify_keys! ### REMOVE when possible class_names = options[''class''] if class_names.blank? class_names = class_name else class_names += '' '' + class_name unless class_names.include? (class_name) end options[''class''] = class_names options end def encode_validation(name, *values) values = values.map {|v| CGI.escape(v.inspect).gsub(''+'', ''%20'')}.join(''_'') "validate_#{name}_#{values}" end def validation_minlength(options) minlength = options[:minimum] if minlength.nil? if range = options[:within] minlength = range.begin end end minlength end def validation_maxlength(options) maxlength = options[:maximum] if maxlength.nil? if range = options[:within] maxlength = range.exclude_end? ? range.end - 1 : range.end end end maxlength end end end end Then, say, in your environment.rb ActiveRecord::Base.class_eval do include BoilerPlate::RailsExtensions::ValidationReflection include BoilerPlate::RailsExtensions::Validations end ActionView::Helpers::InstanceTag.class_eval do include BoilerPlate::RailsExtensions::InstanceTagValidationsSupport end -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/
Is this really enough? What if you have: validates_length_of :foo, :minimum => 10 or any other number of validations that may not allow nil but can be used as a more restrictive validator for presence of data. -- View this message in context: http://www.nabble.com/Introspecting-validates_presence_of-tf2008440.html#a5526552 Sent from the RubyOnRails Users forum at Nabble.com.
Michael Schuerig
2006-Jul-27 23:49 UTC
[Rails] Publishing a plugin (was: Introspecting validates_presence_of)
On Thursday 27 July 2006 19:56, Michael Schuerig wrote:> I hope to make this stuff into a plugin.And so I did. A first, rough version. What I don''t understand is how to publish it, although I had a look at the RailsPluginPackageTask[*]. For the time being I just want to upload all that''s needed to my personal web site where I don''t have SVN support. Michael [*] http://www.mandhro.com/2006/07/03/publising-rails-plug-ins-with-rake/ -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/
Benjamin Curtis
2006-Jul-28 16:01 UTC
[Rails] Publishing a plugin (was: Introspecting validates_presence_of)
I''d recommend using Google''s new SVN hosting (http://code.google.com/ hosting/) and then posting it at http://www.agilewebdevelopment.com/ plugins/. -- Benjamin Curtis http://www.bencurtis.com/ http://www.tesly.com/ -- Collaborative test case management http://www.agilewebdevelopment.com/ -- Resources for the Rails community On Jul 27, 2006, at 4:49 PM, Michael Schuerig wrote:> On Thursday 27 July 2006 19:56, Michael Schuerig wrote: >> I hope to make this stuff into a plugin. > > And so I did. A first, rough version. What I don''t understand is > how to > publish it, although I had a look at the RailsPluginPackageTask[*]. > For > the time being I just want to upload all that''s needed to my personal > web site where I don''t have SVN support. > > Michael > > [*] > http://www.mandhro.com/2006/07/03/publising-rails-plug-ins-with-rake/ > > -- > Michael Schuerig > mailto:michael@schuerig.de > http://www.schuerig.de/michael/ > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060728/6dcd07e4/attachment.html
Michael Schuerig
2006-Jul-28 16:21 UTC
[Rails] Re: Publishing a plugin (was: Introspecting validates_presence_of)
On Friday 28 July 2006 18:00, Benjamin Curtis wrote:> I''d recommend using Google''s new SVN hosting (http://code.google.com/ > hosting/) and then posting it at http://www.agilewebdevelopment.com/ > plugins/.Why Google over RubyForge? Michael -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/
Benjamin Curtis
2006-Jul-28 17:12 UTC
[Rails] Re: Publishing a plugin (was: Introspecting validates_presence_of)
Oh, no reason, I assumed since you were asking the question that either rubyforge or sourceforge weren''t appealing to you. -- Benjamin Curtis http://www.bencurtis.com/ http://www.tesly.com/ -- Collaborative test case management http://www.agilewebdevelopment.com/ -- Resources for the Rails community On Jul 28, 2006, at 9:21 AM, Michael Schuerig wrote:> On Friday 28 July 2006 18:00, Benjamin Curtis wrote: >> I''d recommend using Google''s new SVN hosting (http://code.google.com/ >> hosting/) and then posting it at http://www.agilewebdevelopment.com/ >> plugins/. > > Why Google over RubyForge? > > Michael > > -- > Michael Schuerig > mailto:michael@schuerig.de > http://www.schuerig.de/michael/ > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060728/be673ee5/attachment-0001.html
Michael Schuerig
2006-Jul-28 17:54 UTC
[Rails] Re: Publishing a plugin (was: Introspecting validates_presence_of)
On Friday 28 July 2006 19:10, Benjamin Curtis wrote:> Oh, no reason, I assumed since you were asking the question that > either rubyforge or sourceforge weren''t appealing to you.Ah, that''s been a misunderstanding, then. I just don''t want to go to the trouble of publishing a plugin on *any* of these sites right now. I''m just trying to put it on my own website. I''ve finally figured out what the index listings ought to look like after reading the source code of the plugin installer. Michael -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/