2009-04-14 8 views
6

¿Es normal no obtener el <div class="fieldWithErrors"> envuelto alrededor de las etiquetas de selección que tienen errores de validación? Personalmente, no veo ninguna razón por la cual las etiquetas de selección se deben tratar de manera diferente que otras etiquetas de formulario (entrada, área de texto).Validación de rieles y 'fieldWithErrors' envolver etiquetas de selección

I do obtener el error en error_messages_for y error_message_on métodos para ese campo.

PS. He alterado un poco el ActionView::Base.field_error_proc para obtener etiquetas span en lugar de divs, pero ese no es el problema.

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>" 
} 

Respuesta

2

Como no pude averiguar por qué las etiquetas de selección no se incluyeron en ese Proc, creé un método de ayuda que hace bastante más o menos lo mismo.

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 

lo utilizo en mis puntos de vista, así:

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

Si alguien conoce una manera mejor o más limpia de hacerlo, estoy abierto a sugerencias.

2

me encontré con esta entrada del blog que aparece para hacer frente a esto:

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

Esperamos que sea útil!

+0

Hi. ¡Gracias por la respuesta! Encontré eso también, pero él realmente no especifica si y cómo lo hizo funcionar. Hay un enlace al wiki de Rails, pero está roto. Me gustaría evitar la mayor cantidad posible de agregar una prueba en 'error_message_on' para cada selección porque eso realmente complicaría mis puntos de vista. – andi

+0

Especifica cómo hacerlo funcionar aquí: "La única solución es cambiar la validación en el modelo working_time de project to project_id". Es decir, en la clase de modelo, cambie "validates_presence_of: project" por "validates_presence_of: project_id" –

0

Otra manera, se puede insertar en el método o controlador de nivel, o en el environment.rb:

ActionView :: Base.field_error_proc = proc {| entrada, ejemplo | entrada}

4

El problema (al menos para mí) es que mi f.select :whatever_id estaba buscando en el objeto object.errors para una clave de validación :whatever_id cuando mi era en realidad en :whatever, no :whatever_id.

trabajé en torno a este molesto problema cambiando

object.errors.on(@method_name) 

a

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

Aquí está el diff (contra rieles 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 
1

Ésta es la manera en que yo resolver ese problema

creo una "field_with_errors" específicos de selección envoltorio:

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 

El CSS:

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

Y modifico mis validaciones a: whatever_id en lugar de : lo

validates :whatever_id, :presence => true 

Me estaba olvidando, el seleccionar:

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

Gracias, me pareció útil modificar el si incluir un cheque para una clase "sin errores" en html_tag, cuando se encuentra don No muestra ningún error. Muy útil cuando algunos campos de formulario tienen cosas como javascript datepickers en ellos, que se romperían. – benz001

Cuestiones relacionadas