Skip to content

Commit

Permalink
Merge PR #43413
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelfranca committed Nov 15, 2021
2 parents 39a25ba + 7d2be2e commit 0338221
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 2 deletions.
19 changes: 19 additions & 0 deletions actionview/CHANGELOG.md
@@ -1,3 +1,22 @@
* Infer HTTP verb `[method]` from a model or Array with model as the first
argument to `button_to` when combined with a block:

```ruby
button_to(Workshop.find(1)){ "Update" }
#=> <form method="post" action="/workshops/1" class="button_to">
#=> <input type="hidden" name="_method" value="patch" autocomplete="off" />
#=> <button type="submit">Update</button>
#=> </form>

button_to([ Workshop.find(1), Session.find(1) ]) { "Update" }
#=> <form method="post" action="/workshops/1/sessions/1" class="button_to">
#=> <input type="hidden" name="_method" value="patch" autocomplete="off" />
#=> <button type="submit">Update</button>
#=> </form>
```

*Sean Doyle*

* Support passing a Symbol as the first argument to `FormBuilder#button`:

```ruby
Expand Down
12 changes: 11 additions & 1 deletion actionview/lib/action_view/helpers/url_helper.rb
Expand Up @@ -346,7 +346,7 @@ def button_to(name = nil, options = nil, html_options = nil, &block)

authenticity_token = html_options.delete("authenticity_token")

method = html_options.delete("method").to_s
method = (html_options.delete("method").presence || method_for_options(options)).to_s
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".html_safe

form_method = method == "get" ? "get" : "post"
Expand Down Expand Up @@ -767,6 +767,16 @@ def add_method_to_attributes!(html_options, method)
html_options["data-method"] = method
end

def method_for_options(options)
if options.is_a?(Array)
method_for_options(options.last)
elsif options.respond_to?(:persisted?)
options.persisted? ? :patch : :post
elsif options.respond_to?(:to_model)
method_for_options(options.to_model)
end
end

STRINGIFIED_COMMON_METHODS = {
get: "get",
delete: "delete",
Expand Down
61 changes: 60 additions & 1 deletion actionview/test/template/url_helper_test.rb
Expand Up @@ -35,7 +35,10 @@ class UrlHelperTest < ActiveSupport::TestCase
get "/other" => "foo#other"
get "/article/:id" => "foo#article", :as => :article
get "/category/:category" => "foo#category"
resources :workshops
resources :sessions
resources :workshops do
resources :sessions
end

scope :engine do
get "/" => "foo#bar"
Expand Down Expand Up @@ -208,6 +211,62 @@ def test_button_to_with_false_url_and_block
)
end

def test_button_to_with_new_record_model
session = Session.new(nil)

assert_dom_equal(
%{<form method="post" action="/sessions" class="button_to"><button type="submit">Create Session</button></form>},
button_to("Create Session", session)
)
end

def test_button_to_with_new_record_model_and_block
workshop = Workshop.new(nil)

assert_dom_equal(
%{<form method="post" action="/workshops" class="button_to"><button type="submit">Create</button></form>},
button_to(workshop) { "Create" }
)
end

def test_button_to_with_nested_new_record_model_and_block
workshop = Workshop.new("1")
session = Session.new(nil)

assert_dom_equal(
%{<form method="post" action="/workshops/1/sessions" class="button_to"><button type="submit">Create</button></form>},
button_to([workshop, session]) { "Create" }
)
end

def test_button_to_with_persisted_model
workshop = Workshop.new("1")

assert_dom_equal(
%{<form method="post" action="/workshops/1" class="button_to"><input type="hidden" name="_method" value="patch" autocomplete="off" /><button type="submit">Update</button></form>},
button_to(workshop) { "Update" }
)
end

def test_button_to_with_persisted_model_and_block
workshop = Workshop.new("1")

assert_dom_equal(
%{<form method="post" action="/workshops/1" class="button_to"><input type="hidden" name="_method" value="patch" autocomplete="off" /><button type="submit">Update</button></form>},
button_to(workshop) { "Update" }
)
end

def test_button_to_with_nested_persisted_model_and_block
workshop = Workshop.new("1")
session = Session.new("1")

assert_dom_equal(
%{<form method="post" action="/workshops/1/sessions/1" class="button_to"><input type="hidden" name="_method" value="patch" autocomplete="off" /><button type="submit">Update</button></form>},
button_to([workshop, session]) { "Update" }
)
end

def test_button_to_with_straight_url_and_request_forgery
self.request_forgery = true

Expand Down

0 comments on commit 0338221

Please sign in to comment.