2011-02-03 20 views
29

Chcę mieć przycisk Submit. Aktualizuje jedno pole na przesyłce; submission.state = :submittedJak dodać dodatkowe parametry do formularza button_to?

Teraz mogę utworzyć niestandardową trasę i niestandardową akcję i po prostu wysłać do tego. Ale wydaje się to bardzo ciężkie. Zwłaszcza, że ​​będę miał również przycisk reject i prawdopodobnie więcej. Wymaganie niestandardowej trasy dla każdego z nich wydaje mi się wręcz niemądre.

Byłoby o wiele ładniejszy, czy mogę zrobić coś takiego

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

Które Posta do update sposobu składania i aktualizacji tylko żądane pole.

Ale to nie działa. Jak mogę to sprawić? A może masz lepszy pomysł, jak to zrobić?

Odpowiedz

37

pull request wymienić @AugustinRiedinger zostały połączone i jest dostępny od szyn 4.1.0. Teraz wystarczy dodać opcję params:

params: { state: :submitted } 
+7

Należy zauważyć, że obecnie opcja params nie zezwala na zagnieżdżone hasze. Przykład: 'params: {user: {active: false}}' jest niedozwolone. Możesz ominąć to używając brzydkiego 'params: {:" user [active] "=> true}' – ivanxuu

11

To nie jest tak zwięzły, ale bez rozszerzania szynach, to będzie po mnie przez:

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

więc nie ma innego rozwiązania? Podobnie jak "Wyślij", "submit_url" (składanie),: method =>: put,: params => {: submission => {: state =>: submitted}} ' –

+2

Wygląda na to, że ta ewolucja została rozwinięta, ale musi być nadal zintegrowane: https://github.com/rails/rails/pull/10471 –

5

mam coś podobnego, że działa:

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

+1

Działa to, ale dołącza parametry do łańcucha zapytania, który wydaje się nieco brzydki. –

0

Jak Rails 3.2.1 cię można dodać dodatkowe parametry do skrótu: html_options za pomocą klucza: form.

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

ten nie istniał przed 3.2.1 więc wymagany był bardziej gadatliwy rozwiązanie deklarowania formularz z ukrytych atrybutów.

+3

: html_options nie pozwala dodawać ukrytych elementów wejściowych do formularza, który tworzy button_to. Doda opcje do html wejściowego tagu. Istnieje jednak jedna opcja, którą możesz przekazać do html_options, która wygeneruje ukryte pole w formularzu i jest to opcja metody. Zobacz dokumentację dla przykładów: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to –

3

Tak, jak z tego wyciągnąć wniosek, szyny: https://github.com/rails/rails/pull/10471

Oto co można zrobić, aby mieć swój własny button_to.

W application_helper.rb, dodać te linie:

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 

I z niego korzystać:

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

Enjoy! Baw się dobrze!

+2

Jestem autorem tego PR. Zostało ono zaakceptowane w Railsach, więc opcja 'params' jest teraz dostępna od Rails 4.1. –

1

Jeśli poprawnie odczytałem, co faktycznie chcesz zrobić, aby coś konkretnego, gdy standardowy formularz szyny jest składany w standardowy sposób.

Należy zauważyć, że po przesłaniu formularza za pomocą np.

f.submit "Save Changes"

następnie

params[:commit] = "Save Changes"

Dobrą rzeczą jest to, że może to pozwoli Ci zrobić kilka stosowne rozgałęzienia w akcji kontrolerów aktualizacji.

Złe jest to, że jest kruchy. Jeśli któregoś dnia ty lub ktoś inny zdecyduje się zmienić tekst na przycisku, coś się zepsuje ... co jest złe.

K

8

Dodaj params: {} na końcu, będzie generować 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" } %> 
Powiązane problemy