2011-02-03 11 views
29

Quiero tener un botón Submit. Actualiza un campo en el envío; submission.state = :submitted¿Cómo agregar parámetros adicionales a un botón_para formar?

Ahora, podría hacer una ruta personalizada y una acción personalizada y solo publicar en eso. Pero eso parece muy duro. Especialmente porque también tendré un botón reject y posiblemente más. Necesitar una ruta personalizada & acción para cada uno de esos me parece francamente tonto.

sería mucho más agradable si podía hacer algo como

button_to "Submit", submission_url(submission), :method => :put, :submission => { :state => :submitted } 

cual sería publicar en el método de la presentación update y actualizar sólo el campo deseado.

Pero eso no funciona. ¿Cómo puedo hacer que funcione? ¿O tienes una mejor idea de cómo hacer esto?

Respuesta

37

El pull request mencionado por @AugustinRiedinger se ha fusionado y ahora está disponible a partir de Rails 4.1.0. Ahora sólo tiene que añadir la opción params:

params: { state: :submitted } 
+7

Tenga en cuenta que la opción params actualmente no permite hashes anidados. Ejemplo: 'params: {user: {active: false}}' no está permitido. Puede omitir esto usando los feos 'params: {:" usuario [activo] "=> verdadero}' – ivanxuu

11

No es tan concisa, pero sin extender los carriles, esto me llevará por:

= form_for submission, :html => { :class => "button_to" } do |f| 
    = f.hidden_field :state, :value => :submitted 
    = f.submit "Submit", :class => "link" 
+0

Así que no hay otra solución? Como un 'button_to" Submit ", submission_url (submission),: method =>: put,: params => {: submission => {: state =>: submitted}}' –

+2

Aparentemente esta evolución ha sido desarrollada, pero necesita integre aún: https://github.com/rails/rails/pull/10471 –

5

que tienen algo similar que funciona:

button_to "Submit", submission_url(submission, :submission => { :state => :submitted }), :method => :put

+1

Esto funciona, pero agrega los parámetros a la cadena de consulta que parece un poco feo. –

0

A partir de Rails 3.2.1 puede agregar parámetros adicionales al hash html_options usando la tecla: form.

http://apidock.com/rails/v3.2.1/ActionView/Helpers/UrlHelper/button_to

Esto no existía antes de la 3.2.1 por lo que se requiere la solución más detallado de declarar un formulario con atributos ocultos.

+3

: html_options no le permite agregar elementos de entrada ocultos al formulario que button_to crea. Agregará opciones al html de la etiqueta de entrada. Sin embargo, hay una opción que puede pasar a html_options que generará un campo oculto en el formulario y esa es la opción de método. Consulte la documentación para ver ejemplos: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to –

3

Así, a partir de este carriles de extracción solicitud: https://github.com/rails/rails/pull/10471

Esto es lo que puede hacer para tener su button_to personalizado.

En application_helper.rb, añadir estas líneas:

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 

y utilizarla:

= button_to_with_params 'Awesome button', awesome_action_path, method: :put, :params => {:my_param => 'my_value'} 

disfrutar! Diviértete barandilla!

+2

Soy el autor de ese PR. Fue aceptado en Rails por lo que la opción 'params' ya está disponible desde Rails 4.1. –

1

Si leo correctamente las cosas, lo que realmente quiere es hacer algo específico cuando se envía un formulario estándar de rieles de la manera estándar.

Observe que cuando se envía un formulario usando, p.

f.submit "Save Changes"

continuación

params[:commit] = "Save Changes"

Lo bueno de esto es que puede permitir que usted pueda hacer algo de ramificación en la apropiada acción de actualización controladores.

Lo malo es que es frágil. Si un día tú u otra persona deciden cambiar el texto del botón, las cosas se rompen ... lo cual es malo.

K

8

Añadir params: {} al final, se generará 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" } %> 
Cuestiones relacionadas