2010-06-01 10 views
8

Tengo un formulario de suscripción que anida asociaciones/atributos como quiera que los llame.Rieles: Deshacerse de los errores de validación genéricos "X no es válido"

Mi jerarquía es la siguiente:

class User < ActiveRecord::Base 
    acts_as_authentic 
    belongs_to :user_role, :polymorphic => true 
end 

class Customer < ActiveRecord::Base 
    has_one :user, :as => :user_role, :dependent => :destroy 
    accepts_nested_attributes_for :user, :allow_destroy => true 
    validates_associated :user 
end 

class Employee < ActiveRecord::Base 
    has_one :user, :as => :user_role, :dependent => :destroy 
    accepts_nested_attributes_for :user, :allow_destroy => true 
    validates_associated :user 
end 

tengo algunas cosas de validación en estas clases también. Mi problema es que si trato de crear un cliente (o empleado, etc.) con un formulario en blanco, obtengo todos los errores de validación que debo obtener más algunos genéricos como "El usuario no es válido" y "El cliente no es válido". los errores me sale algo como:

user.login can't be blank 
User is invalid 
customer.whatever is blah blah blah...etc 
customer.some_other_error etc etc 

Puesto que hay al menos un campo no válido en el modelo de usuario anidado, un extra de "X no es válido" se añade mensaje a la lista de errores. Esto confunde a mi cliente y me pregunto si hay una forma rápida de hacerlo en lugar de tener que archivar los errores yo mismo.

Respuesta

6

La respuesta de Salil fue casi correcta, pero nunca lo hizo al 100%. Aquí está la forma correcta de hacerlo:

def after_validation 
    # Skip errors that won't be useful to the end user 
    filtered_errors = self.errors.reject{ |err| %{ person }.include?(err.first) } 

    # recollect the field names and retitlize them 
    # this was I won't be getting 'user.person.first_name' and instead I'll get 
    # 'First name' 
    filtered_errors.collect{ |err| 
     if err[0] =~ /(.+\.)?(.+)$/ 
     err[0] = $2.titleize 
     end 
     err 
    } 

    # reset the errors collection and repopulate it with the filtered errors. 
    self.errors.clear 
    filtered_errors.each { |err| self.errors.add(*err) } 
    end 
+0

Además, he propuesto una solicitud de función como una mejor solución que esta solución temporal: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/5632-validates_associated-should-be-allowed -to-not-create-a-error # ticket-5632-2 – DJTripleThreat

+0

Recibo el error "no hay conversión implícita de Symbol en cadena" – Chemist

+0

@Chemist esto funcionaba para una versión anterior de los rieles. Intente editar el código proporcionado para que funcione correctamente con la versión que está utilizando. – DJTripleThreat

3

Uso after_validation método

def after_validation 
    # Skip errors that won't be useful to the end user 
    filtered_errors = self.errors.reject{ |err| %w{ user User }.include?(err.first) } 
    self.errors.clear 
    filtered_errors.each { |err| self.errors.add(*err) } 
    end 

EDITADO

Nota: -

Añadir el siguiente en la lista en su caso se trata de usuario o usuario. puede agregar múltiples si tiene múltiples assosciation separadas por espacio.

%w{ User user }.include?(err.first) #### This piece of code from the above method has logic which reject the errors which won't be useful to the end user 
+0

Ok, esto parece prometedor! :) Creo que tienes un error de gramática en "Nota: -" Eso me confunde ... "¿Agregar el ... ???" Además, ¿dónde debería poner esta función? en cada modelo que hace esto? ¿Es esto una función que reemplaza a ARB? – DJTripleThreat

+0

lo siento por la gramática :). pon este método en todos los modelos donde escribes ** validates_associated ** – Salil

+0

Ok, te votaré ahora porque esto funciona principalmente. Un problema: en lugar de esto: ** Inicio de sesión ** es demasiado corto (mínimo 3 caracteres) ** Contraseña ** es demasiado corta (mínimo 4 caracteres) ** La confirmación de la contraseña ** es demasiado corta (mínimo es de 4 caracteres) me estoy haciendo esto: ** ** User.login es demasiado corto (mínimo es de 3 caracteres) ** ** user.password es demasiado corto (mínimo es de 4 caracteres) ** usuario .conword confirmation ** es demasiado corto (mínimo 4 caracteres) Si puede resolver cómo solucionarlo, aceptaré su respuesta. – DJTripleThreat

Cuestiones relacionadas