Question

J'ai action pour créer une forme qui génère potentiellement des erreurs (à savoir le prénom est manquant) et redirige ensuite.

Le problème est que lorsque la redirection se forme les erreurs se perdent. Comment pourrais-je passer ces erreurs de forme dans une session à afficher de nouveau sous la forme d'origine (qui doit encore être rempli avec les détails précédents, comme dans le comportement error_messages d'origine)?

Merci!


Le code:

def create
  @contact = Contact.new(params[:contact])
  if @contact.save
    flash[:notice] = "Sent."
  else
    flash[:notice] = "Error."
  end
end
Était-ce utile?

La solution

Ceci est un problème délicat que j'ai eu du mal avec moi-même. La première question que je voudrais poser est pourquoi avez-vous besoin de rediriger lorsque des erreurs sont trouvées? vous obligeant à rendre l'action quand il y a des erreurs a été une décision consciente des concepteurs du cadre Rails en raison de problèmes de complexité et de la convivialité.

Voici le gros problème, donc dans votre action, vous créez une instance d'un modèle à l'aide params, la validation de l'objet tombe en panne et que vous décidez de rediriger vers une autre action. Avant de rediriger vers une autre action que vous auriez à enregistrer l'état actuel de votre instance de modèle à la session et rediriger vers l'action: foo. Dans l'action: foo vous auriez à mettre à jour les essayer de nouveau attributs et de transmettre les erreurs à la vue par une variable d'instance. Le problème ici est que vous couplant des actions dans votre contrôleur qui est une mauvaise chose (une action est dépendante de l'autre). Il y a une foule d'autres problèmes que je pouvais taper à propos pour toujours, mais si vous avez seulement besoin de faire cela pour une seule ressource, voici comment je le ferais:

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 / choses / new.html.erb

<% if defined?(@errors) %>
<% #do something with @errors to display the errors %>
<% end %>

<!-- render the form stuff -->

Je sais ce que vous pensez ... c'est hideux. Croyez-moi, je l'ai fait beaucoup de tentatives pour résoudre ce problème et je suis venu à réaliser, le mécanisme des rails développeurs ont choisi est le meilleur et le plus facile de traiter avec des erreurs.

Autres conseils

La convention Rails est de rendre le point de vue de l'action initiale plutôt que de faire une redirection. Donc, votre code ressemblera à ceci:

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

En cas de configuration supplémentaire nécessaire à faire pour l'action new, extraire le code commun dans une méthode privée et l'appeler dans un before_filter pour les new et create.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top