Come passare errori di forma in seduta o Flash? [Rails 2.3.5]
-
24-09-2019 - |
Domanda
Ho una creare un'azione per una forma che potenzialmente genera errori (cioè nome manca) e poi reindirizzamenti.
Il problema è che, quando il reindirizzamento avviene quelli sotto forma di errori perdersi. Come potrei passare quegli errori di forma in una sessione da visualizzare di nuovo nella forma originale (che dovrebbe ancora essere compilato con i dettagli precedenti, come nel comportamento messaggi_errore originale)?
Grazie!
Il codice:
def create
@contact = Contact.new(params[:contact])
if @contact.save
flash[:notice] = "Sent."
else
flash[:notice] = "Error."
end
end
Soluzione
Questo è un problema difficile che ho avuto problemi con me stesso. La prima domanda che vorrei porre è perché avete bisogno di reindirizzare quando vengono trovati errori? costringendo a rendere l'azione quando ci sono errori è stata una decisione consapevole dei progettisti del framework Rails a causa della complessità e usabilità preoccupazioni.
Ecco il grande problema, in modo da nella vostra azione, si crea un'istanza di un modello utilizzando params, la convalida oggetto non riesce e si decide di reindirizzare a un'altra azione. Prima di reindirizzamento a un'altra azione che avrebbe dovuto salvare lo stato corrente dell'istanza modello per la sessione e quindi reindirizzare all'azione: foo. In azione: pippo dovreste riprovare ad aggiornare gli attributi e superare gli errori alla vista tramite una variabile di istanza. Il problema qui è che si sta accoppiando azioni nel vostro controller, che è una cosa negativa (un'azione è dipendente dall'altra). Ci sono una miriade di altri problemi che ho potuto digitare about sempre, ma se avete solo bisogno di fare questo per una risorsa, ecco come lo farei:
config / routes.rb
map.resources :things, :member => { :create_with_errors => :get }
things_controller.rb
def new
@thing = Thing.new
end
def create
@thing = Thing.create(params[:thing])
if @thing.save
redirect_to things_path
else
session[:thing] = @thing
redirect_to create_errors_thing_path(@thing)
end
end
def create_with_errors
@thing = session[:thing]
@errors = @thing.errors
render :action => :new
end
app / views / cose / new.html.erb
<% if defined?(@errors) %>
<% #do something with @errors to display the errors %>
<% end %>
<!-- render the form stuff -->
Lo so cosa state pensando ... questo è orribile. Fidati di me, ho fatto un sacco di tentativi di affrontare questo problema e sono venuto a realizzare, il meccanismo gli sviluppatori rotaie hanno scelto è il modo migliore e più semplice per affrontare gli errori.
Altri suggerimenti
La convenzione in Rails è quello di rendere l'opinione della azione originale piuttosto che fare un redirect. Quindi, il codice sarebbe simile a questa:
def create
@contact = Contact.new(params[:contact])
if @contact.save
flash[:notice] = 'Sent.'
redirect_to @contact
else
flash.now[:notice] = 'Error.'
render :new
end
end
Se non v'è alcuna configurazione aggiuntiva doveva essere fatto per l'azione new
, estrarre il codice comune in un metodo privato e lo chiamano in un before_filter
sia per new
e create
.