Make `button_to` more model-aware
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> ``` Prior to this change, the constructed `<form>` was always submitted with a `[method="post"]` and _always_ omitted the `<input type="hidden" name="_method" value="...">` field, regardless of the return value of the "model" argument's `#persisted?` predicate.
This commit is contained in:
parent
9f980664fc
commit
7d2be2e011
|
@ -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*
|
||||
|
||||
* Add `:day_format` option to `date_select`
|
||||
|
||||
date_select("article", "written_on", day_format: ->(day) { day.ordinalize })
|
||||
|
|
|
@ -332,7 +332,8 @@ module ActionView
|
|||
remote = html_options.delete("remote")
|
||||
params = html_options.delete("params")
|
||||
|
||||
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"
|
||||
|
@ -753,6 +754,16 @@ module ActionView
|
|||
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",
|
||||
|
|
|
@ -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"
|
||||
|
@ -161,6 +164,62 @@ class UrlHelperTest < ActiveSupport::TestCase
|
|||
)
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue