rails icon indicating copy to clipboard operation
rails copied to clipboard

Implement `button_to` in terms of `form_tag`

Open seanpdoyle opened this issue 2 years ago • 1 comments

Motivation / Background

While the ergonomics of calling button_to match those of form_for, form_with, or even form_tag, the implementation doesn't use much of those helper's existing infrastructure. There are chunks of logic repeated and re-implemented. For example:

  • determining the [action] and [method] attributes for the <form>
  • rendering an <input type="hidden" name="_method"> for methods other than POST or GET
  • generating and rendering an authenticity token input
  • content exfiltration
  • encoding [data-remote] for UJS integration

Detail

This commit implements more of button_to in terms of the form_tag helper method defined in FormTagHelper. That method handles responsibilities like determining [method], rendering <input type="hidden">, etc.

The only outward-facing changes (reflected in test suite cases) involve the order of the <form> element's content, and the introduction of an [accept-charset="UTF-8"] attribute.

The <button> element will be rendered after hidden fields instead of before (the previous behavior).

Similarly, the [accept-charset] attribute wasn't being rendered before, but is rendered by form_tag. The form_tag helper doesn't currently expose a mechanism to skip that attribute (in the same way that :enforce_utf8 is being used here to skip the <input type="hidden">.

Additional information

As part of these changes, this commit also excises the method_tag and token_tag private helpers out of the UrlHelper module and into the FormTagHelper module, since that's the only remaining call site. The previous implementation relied on the fact that both UrlHelper and FormTagHelper end up being mixed into an ActionView::Base instance, so the cross-module private boundary wasn't effective.

Checklist

Before submitting the PR make sure the following are checked:

  • [x] This Pull Request is related to one change. Changes that are unrelated should be opened in separate PRs.
  • [x] Commit message has a detailed description of what changed and why. If this PR fixes a related issue include it in the commit message. Ex: [Fix #issue-number]
  • [x] Tests are added or updated if you fix a bug or add a feature.
  • [x] CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature. Minor bug fixes and documentation changes should not be included.

seanpdoyle avatar Dec 09 '23 15:12 seanpdoyle

Using the existing form tag helpers for button_to makes sense to me. Also, form tags like token_tag and method_tag seem more at place in FormTagHelper, especially because they are already referenced in FormTagHelper.

p8 avatar Dec 11 '23 20:12 p8