Rails 3 link_to generator for :post, :put, & :dele

2019-01-26 06:50发布

问题:

I recently ran into this problem: Rails 3 link_to (:method => :delete) not working

In which I was confused why my link_to 'test', test_path(:test => test), :method => :post wasn't working (why it was GETting rather than POSTing). As the post above suggests, it was because I didn't have the Rails javascript files, which handles dynamically making the form on-the-fly for :post, :put & :delete.

I'm not sure I especially like relying on javascript to do this for me, as I'd like my app to be fully functional with javascript disabled; it's how I like to develop (so I know I've got all my Rails programming functionality works correctly), and when I do wire my app up with javascript, I don't have to worry about duplicating this functionality, since I usually wipe the stock javascripts file generated by Rails.

I read somewhere that, technically, hyperlinks (anchor elements) should only really be used for GET requests, and that buttons (as part of form elements) should be used for the other methods.

So, my two questions:

  1. Is there a gem out there that will rewrite any link_to ... :method => in my view to a form element on-the-fly when my views are rendered?
  2. If not, how would I hook into the view parser to write my own? (using HAML, preferrably)

Essentially, what I would like is to write this in my HAML file:

= link_to 'Test Link', some_path(:with => some_resource), :method => :post

... and have my rendered HTML output come out with this:

<form action="some_path?with=some_resource" method="post">
  <!-- insert appropriate _method hidden field here -->
  <!-- add appropriate csrf token and whatnot -->
  <button type="submit">Test Link</button>
</form>

... so that all the link_to helpers with defined methods (thus, will not affect plain links whose verb is GET) will work without javascript?


I'd also appreciate any thoughts about the why part of this question, specifically why the Rails team decided to keep this functionality tied to javascript rather than doing this through pure HTML?

回答1:

It seems that you really want a single element form (in this case, a button). If so, you want the button_to helper:

button_to 'Test Link', some_path(:with => some_resource), :method => :post

This will generate a form with an input[type=submit] element inside of it.

Without Javascript, you cannot have a hyperlink that will submit using a HTTP verb other than "GET."

If you need more style / control of the form being rendered by button_to, you can do something like this:

module LinksHelper
  def link_form(text, destination, options = {})
    form_tag(destination, :method => options.delete(:method)) do
      <<-HTML
        <!-- some HTML code here -->
        <button type="submit">#{text}</button>
        <!-- some more HTML code here -->
      HTML
    end
  end
end