Je veux avoir un bouton Submit
. Il met à jour un champ sur la soumission; submission.state = :submitted
Maintenant, je pourrais faire un itinéraire personnalisé et une action personnalisée et poster juste à cela. Mais cela semble vraiment lourd. Surtout que je vais aussi avoir un bouton reject
et peut-être plus. Avoir besoin d'un itinéraire et d'une action personnalisés pour chacun de ces objectifs me semble carrément ridicule.
Ce serait beaucoup mieux si je pouvais faire quelque chose comme
button_to "Submit", submission_url(submission), :method => :put, :submission => { :state => :submitted }
Qui publierait dans la méthode update
de la soumission et ne mettrait à jour que le champ souhaité.
Mais ça ne marche pas. Comment puis-je le faire fonctionner? Ou avez-vous une meilleure idée de la façon de procéder?
La demande d'extraction } mentionnée par @AugustinRiedinger a été fusionnée et est maintenant disponible à partir de Rails 4.1.0. Ajoutez maintenant l'option params
:
params: { state: :submitted }
Ce n'est pas aussi concis, mais sans l'extension de Rails, cela me permettra de:
= form_for submission, :html => { :class => "button_to" } do |f|
= f.hidden_field :state, :value => :submitted
= f.submit "Submit", :class => "link"
Ajoutez des paramètres: {} à la fin, cela générera hidden_field
<%= button_to user.name, user, class:"btn btn-default", style:"", method: :patch, remote: true, params: { a_field: false, an_other_field:"a new value" } %>
Ainsi, à partir de cette demande d'extraction Rails: https://github.com/Rails/rails/pull/10471
Voici ce que vous pouvez faire pour avoir votre bouton personnalisé.
Dans application_helper.rb
, ajoutez ces lignes:
module ApplicationHelper
// Unfortunately these 2 methods need to be redefined. I don't know how I could access the original ones.
def token_tag(token=nil)
if token != false && protect_against_forgery?
token ||= form_authenticity_token
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
else
''
end
end
def method_tag(method)
tag('input', type: 'hidden', name: '_method', value: method.to_s)
end
def button_to_with_params(name = nil, options = nil, html_options = nil, &block)
html_options, options = options, name if block_given?
options ||= {}
html_options ||= {}
html_options = html_options.stringify_keys
convert_boolean_attributes!(html_options, %w(disabled))
url = options.is_a?(String) ? options : url_for(options)
remote = html_options.delete('remote')
params = html_options.delete('params') { Hash.new }
method = html_options.delete('method').to_s
method_tag = %w{patch put delete}.include?(method) ? method_tag(method) : ''.html_safe
form_method = method == 'get' ? 'get' : 'post'
form_options = html_options.delete('form') || {}
form_options[:class] ||= html_options.delete('form_class') || 'button_to'
form_options.merge!(method: form_method, action: url)
form_options.merge!("data-remote" => "true") if remote
request_token_tag = form_method == 'post' ? token_tag : ''
html_options = convert_options_to_data_attributes(options, html_options)
html_options['type'] = 'submit'
button = if block_given?
content_tag('button', html_options, &block)
else
html_options['value'] = name || url
tag('input', html_options)
end
inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
params.each do |name, value|
inner_tags.safe_concat tag(:input, type: "hidden", name: name, value: value.to_param)
end
content_tag('form', content_tag('div', inner_tags), form_options)
end
end
Et pour l'utiliser:
= button_to_with_params 'Awesome button', awesome_action_path, method: :put, :params => {:my_param => 'my_value'}
Prendre plaisir! Amusez-vous bien
Si je lis les choses correctement, ce que vous voulez réellement faire est spécifique lorsqu'un formulaire Rails standard est soumis de manière standard.
Notez que lorsqu'un formulaire est soumis en utilisant, par exemple,.
f.submit "Save Changes"
puis
params[:commit] = "Save Changes"
L'avantage, c'est que cela peut vous permettre de créer des branches appropriées dans l'action de mise à jour des contrôleurs.
La mauvaise chose est que c'est fragile. Si un jour vous ou quelqu'un d'autre décide de changer le texte du bouton, les choses se cassent ... ce qui est mauvais.
K
A partir de Rails 3.2.1, vous pouvez ajouter des paramètres supplémentaires au hachage: html_options en utilisant la clé: form.
http://apidock.com/Rails/v3.2.1/ActionView/Helpers/UrlHelper/button_to
Cela n'existait pas avant la version 3.2.1, il fallait donc une solution plus détaillée pour déclarer un formulaire avec des attributs cachés.