We can use form_for or form_tag to build forms in Rails. But their parameters act differently, which always bites me.
For example, I have to wrap html options into a html
key when I change from
form_tag to form_for.
1 2 3 |
|
And as the 3rd parameter of f.select
is options than html_options.
So I have to add an empty hash {}
there to skip it.
1 2 3 4 5 6 |
|
Why they acts differently? Isn’t f.select built on select_tag?
The short answer is NO. f.select is not built on select_tag. Let’s dig into the source.
Here’s where form_for defined.
1 2 3 4 5 6 7 8 9 10 |
|
In FormHelper above also defined a class named ActionView::Helpers::FormBuilder. The form_for uses the FormBuilder.
Most methods in FormHelper are delegated by FormBuilder.
1 2 3 4 5 6 7 8 |
|
Unlike text_field, select helper defined in ActionView::Helpers::FormOptionsHelper. And a select method in FormBuilder delegates the FormOptionsHelper#select.
text_field or select finnally use classes under module ActionView::Helpers::Tags
FormTag and SelectTag are defined in ActionView::Helper::FormTagHelper
ActionView::Helper::FormTagHelper seems totally another implement. Most tags helper are component directly in the methods. eg.
1 2 3 |
|
select_tag and FormBuilder#select do dot shere the implement. They implement the include_blank and other options separately. Is it a historical reason?
How to avoid converts?
Use form object to always use form_for style.