I’m currently using a single form partial to handle multiple objects that are all using STI. This usually isn’t a problem because the form_for helper lets you keep the actual object anonymous, like this:
<p><b>Name</b><br /><%= region_form.text_field :name %></p>
But what happens when you want to use a helper that doesn’t work so well with the
region_form.text_fieldobjects?
I did a little bit of digging into the default object that is passed into the partial, and this is what I found:
region_form.object_name
This lets me implement my multiple select for every type of object, without having to specify anything explicitly.
Example:
In the view:
<% form_for(:province, :url => provinces_path) do |f| %>
<%= render :partial => 'shared/region_form', :object => f %>
<p><%= submit_tag "Create" %> or <%= link_to 'Cancel', provinces_path %></p>
<% end %>
In the helper shared/_region_form.html:
<p><b>Name</b><br /><%= region_form.text_field :name %></p>
<p><label for="alias_region_id">Aliased By:</label><br />
<%= select_tag(
"#{region_form.object_name}[aliased_by][]",
options_from_collection_for_select(
Region.find(:all),
'id',
'title',
instance_variable_get("@#{region_form.object_name}").aliased_by_ids),
:multiple => true
)
%></p>
So, we use a combination of region_form.object name and instance_variable_get to make the form handle whatever object we throw at it.
Yay ruby!