tags that have validation...">

Validation and FieldWithErrors field selection tags

Is it normal behavior to not get select <div class="fieldWithErrors"> tags that have validation errors? I personally do not see the reasons why select tags should be processed differently than tags of other forms (input, textarea).

I get an error in the error_messages_for and error_message_on for this field.

PS. I changed the value of ActionView::Base.field_error_proc to get span tags instead of div, but this is not a problem.

 ActionView::Base.field_error_proc = Proc.new { |html_tag, instance| #if I puts html_tag here I only get the <input> tags "<span class=\"fieldWithErrors\">#{html_tag}</span>" } 
+6
validation ruby-on-rails actionview
source share
5 answers

Since I could not find out why select tags were not included in this Proc, I created a helper method that does preety very much the same.

 def field_with_error(object, method, &block) if block_given? if error_message_on(object, method).empty? concat capture(&block) else concat '<span class="fieldWithErrors">' + capture(&block) + '</span>' end end end 

I use it in my views like this:

 <% field_with_error @some_object, :assoc do %> <%= f.select(:assoc_id, @associations.collect {|assoc| [ asoc.name, assoc.id ] }) %> <% end %> 

If someone knows a better or cleaner way to do this, I am open to suggestions.

+2
source share

The problem (at least for me) was that my f.select :whatever_id looking at the object.errors object for the key :whatever_id , when my check was actually on :whatever , not :whatever_id .

I circumvented this nasty problem by changing

 object.errors.on(@method_name) 

to

 object.errors.on(@method_name) || object.errors.on(@method_name.gsub(/_id$/, '')) 

Here's the diff (versus Rails 2.3.4):

 diff --git a/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb index 541899e..5d5b27e 100644 --- a/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb +++ b/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb @@ -247,7 +247,7 @@ module ActionView alias_method :tag_without_error_wrapping, :tag def tag(name, options) if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name)) + error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name) || object.errors.on(@method_name.gsub(/_id$/, ''))) else tag_without_error_wrapping(name, options) end @@ -256,7 +256,7 @@ module ActionView alias_method :content_tag_without_error_wrapping, :content_tag def content_tag(name, value, options) if object.respond_to?(:errors) && object.errors.respond_to?(:on) - error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name)) + error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name) || object.errors.on(@method_name.gsub(/_id$/, ''))) else content_tag_without_error_wrapping(name, value, options) end 
+4
source share

I found this blog post which seems to relate to this:

http://blog.invalidobject.com/2007/09/16/rails-error-wrapping-for-select-input-fields-of-referenced-models

Hope this is helpful!

+2
source share

Here is how I solve this problem.

I create a specific select field_with_errors wrapper:

 ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| if html_tag =~ /^<input/ %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe elsif html_tag =~ /^<select/ %{<div class="field_with_errors" id="select-error">#{html_tag}</div>}.html_safe else %{<div class="field_with_errors">#{html_tag}</div>}.html_safe end end 

CSS:

 #select-error { border: 1px solid red; overflow-y: auto; overflow-x: hidden; } 

And I change my checks to: what_id instead of: any

 validates :whatever_id, :presence => true 

I forgot, select:

 f.collection_select(:whatever_id, Whatever.all, :id, :name, prompt: t(:please_choose)) 
+1
source share

Another way can be inserted at the method or controller level or in environment.rb:

ActionView :: Base.field_error_proc = proc {| input, instance | input}

0
source share

All Articles