2010-06-01 3 views
8

Ho un modulo di registrazione che ha associazioni/attributi nidificati qualunque sia il nome che si desidera chiamare.Rails: eliminazione degli errori di convalida generici "X non valido"

mio Gerarchia è questo:

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 

ho alcune cose convalida in queste classi pure. Il mio problema è che se provo a creare e Cliente (o Dipendente ecc.) Con un modulo vuoto ottengo tutti gli errori di validazione che dovrei ottenere più alcuni Generici come "L'utente non è valido" e "Il cliente non è valido" Se eseguo l'iterazione gli errori che ottenere qualcosa di simile:

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

Poiché non v'è almeno un campo non valido nel modello User nidificato, un extra di "X non è valido" si aggiunge messaggio alla lista degli errori. Questo confonde il mio cliente e quindi mi chiedo se c'è un modo rapido per farlo, invece di dover filtrare da solo gli errori.

risposta

6

La risposta di Salil era quasi giusta ma non l'ha mai fatto al 100%. Ecco il modo corretto per farlo:

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

Inoltre, ho proposto una richiesta di funzionalità come soluzione migliore di questo work-around: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/5632-validates_associated-should-be-allowed -to-not-create-an-error # ticket-5632-2 – DJTripleThreat

+0

Ricevo l'errore "nessuna conversione implicita di Symbol in String" – Chemist

+0

@Chemist questo funzionava per una versione precedente di rails. Prova a modificare il codice fornito in modo che funzioni correttamente con la versione che stai utilizzando. – DJTripleThreat

3

Usa after_validation metodo

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 

CURA

Nota: -

Aggiungere il seguente nella lista nel tuo caso è l'utente o utente. puoi aggiungere più se hai più assosciazioni separate dallo spazio.

%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 questo sembra promettente! :) Penso che tu abbia un errore di grammatica sotto "Nota: -" questo mi confonde .. "Aggiungi il ... ???" Inoltre, dove dovrei inserire questa funzione? in ogni modello che fa questo? È una funzione di override di ARB? – DJTripleThreat

+0

scusate per la grammatica :). metti questo metodo in tutti i modelli in cui scrivi ** validates_associated ** – Salil

+0

Ok ti inviterò ora perché questo funziona principalmente. Un problema però: invece di questo: ** Login ** troppo corto (minimo 3 caratteri) ** Password ** troppo breve (minimo 4 caratteri) ** Conferma password ** troppo breve (minimo è di 4 caratteri) sto ottenendo questo: ** ** User.login è troppo breve (minimo è di 3 caratteri) ** ** User.password è troppo breve (minimo è di 4 caratteri) ** User .password conferma ** è troppo breve (minimo 4 caratteri) Se riesci a capire come risolvere questo problema accetterò la tua risposta. – DJTripleThreat