I’ve always found Rails form helpers select tags cumbersome to work with, mainly because the abstraction buries control over how the <option>
tags are rendered. Consider this example in the Rails docs.
select(:post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })
It emits the following HTML.
<select name="post[person_id]" id="post_person_id">
<option value="">None</option>
<option value="1">David</option>
<option value="2" selected="selected">Eileen</option>
<option value="3">Rafael</option>
</select>
What if you want the blank value to appear at the end of the list? How would you add an attribute to an <option>
tag? You’re in for a world of pain as you have to reach deep into the internals of the Rails form helpers.
Phlex and Superform
I coded Superform after getting angry at how little control I had over Rails helpers and how gross the syntax looks. Here’s the equivalent code in Superform, which is a Rails form helper I built from scratch on top of Phlex.
Blank options
render field(:contact).select nil, Person.select(:name, :id)
Want that blank to be at the end? Just move the nil
argument to the end.
render field(:contact).select Person.select(:name, :id), nil
Want the blank to say “None”? Here’s how Rails does it.
select(:post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: "None" })
Here’s how Superform does it.
render field(:contact).select Person.select(:name, :id), [nil, "None"]
More control over the option tag
Here’s the most complex, ungrouped form from the Rails docs.
collection_select(:post, :category_id, Category.all, :id, :name, { disabled: -> (category) { category.archived? } })
In Superform, the Proc gymnastics are unnecessary and the resulting code is much cleaner.
render field(:category_id).select do |s|
Category.select(:id, :name).each do |category|
s.option(disabled: category.archived?, id: category.id) do
category.name
end
end
# Instead of the `[nil, "None"]` array passed into the `select` method.
s.blank_option "None"
end
In this example, Superform required more lines of code; however, it’s much clearer what HTML is being emitted and developers have full control over the HTML output for each option tag.
Going deeper
The Phlex on Rails video course will go even deeper on how to use Superform and Phlex to build complex forms while giving developers better control over the HTML.