Disons que j'ai un modèle d'article, et dans la vue "nouvelle" de l'article, j'ai deux boutons, "Publier" et "Enregistrer le brouillon".
Ma question est de savoir comment puis-je savoir quel bouton est cliqué dans le contrôleur.
J'ai déjà une solution mais je pense qu'il doit y avoir une meilleure solution. Ce que j'utilise actuellement dans la vue est:
<div class="actions">
<%= f.submit "Publish" %>
<%= f.submit "Save Draft", :name => "commit" %>
</div>
Donc, dans le contrôleur, je peux utiliser la chaîne params [: commit] pour gérer cette action.
def create
@article = Article.new(params[:article])
if params[:commit] == "Publish"
@article.status = 'publish'
// detail omitted
end
@article.save
end
Mais je pense que l'utilisation de la chaîne liée à la vue n'est pas bonne. Pourriez-vous me dire une autre façon d'accomplir cela?
UPDATE : Étant donné que ces boutons sont sous la même forme, ils vont tous à l'action "créer", et c'est OK pour moi. Ce que je veux, c'est gérer cela dans l'action de création, comme donner au modèle d'article une colonne "statut" et contenir "public" ou "brouillon".
Cela a été couvert dans Railscast épisode 38 . Utiliser le hachage params
pour détecter le bouton sur lequel vous avez cliqué est la bonne approche:
Affichage:
<%= submit_tag 'Create' %>
<%= submit_tag 'Create and Add Another', name: 'create_and_add' %>
Contrôleur:
if params[:create_and_add]
# Redirect to new form, for example.
else
# Redirect to show the newly created record, for example.
end
Nous avons résolu en utilisant contraintes avancées dans Rails.
L'idée est d'avoir le même chemin (et donc la même route & action nommée) mais avec des contraintes de routage vers différentes actions.
resources :plan do
post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
CommitParamRouting
est une classe simple qui a une méthode matches?
qui renvoie vrai si le paramètre de validation correspond à l'instance attr donnée. valeur.
Ceci est disponible sous forme de gemme commit_param_matching .
cela peut aussi être fait sur l'aide form_for comme ceci
<%= f.submit "Publish",name: "publish", class: "tiny button radius success" %>
<%= f.submit 'Mark as Draft', name: "draft", class: "tiny button radius " %>
et la logique est la même sur le contrôleur
if params[:publish]
// your code
elsif params[:draft]
// your code
end
Je me souviens d'avoir rencontré ce problème une fois. Vous ne pouvez pas conserver deux boutons, puis appeler une action basée sur les paramètres [: commit]. le bouton soumettre onclick va appeler l'url à laquelle le formulaire fait référence. Il existe certaines mauvaises façons d'obtenir le comportement souhaité. Gardez un bouton pour appeler l'action à laquelle le formulaire fait référence et pour obtenir un autre bouton pour appeler une action, j'ai utilisé un link_to puis changé les styles pour correspondre à un bouton. En outre, vous pouvez également utiliser jQuery pour modifier l'URL que le formulaire appelle, ce qui permet de décider quelle action est appelée au moment de l'exécution. J'espère que cela t'aides.
Vous pouvez également définir des attributs data
sur les boutons d'envoi et utiliser JavaScript pour modifier l'action form
en cliquant sur l'un des boutons
j'utilise généralement la suggestion de John Topley (voir la réponse ci-dessus). une autre façon consiste à utiliser JQuery/JS en changeant l'attribut d'action de formulaire - en cliquant sur l'exemple du bouton soumettre:
form_tag({} ,:method => 'post', :id => 'reports_action') do
.......
.......
submit_tag 'submit', :onclick => "return changeAction();"
end
puis .....
function changeAction(){
$('#reports_action').attr('action','my_new_action');
}