Using SimpleForm in a Rails 6 app, I have a nested object that is created multiple times on the new method for the parent object:
def new
@issue = @issueable.issues.new
@cat_patchvault = Catalog.find_by_slug("patchvault")
@cat_bb6 = Catalog.find_by_slug("blue-book-6")
@issue.catalog_entries.build(catalog_id: @cat_patchvault.id)
@issue.catalog_entries.build(catalog_id: @cat_bb6.id)
@issue.reorders.new
@issue.issue_variations.new
respond_with @issue
end
These objects all create and the catalog entries partials are rendered and show the correct catalog in the select dropdown, however, I wanted to change the legend of the fieldset to reflect the catalog and move this to a hidden field.
The select in question:
<%= form.input :catalog_id,
label: 'Catalog',
as: :select,
prompt: 'Choose Catalog',
collection: Catalog.all.order(:name),
label_method: lambda { |cl| "#{cl.name} #{cl.version if cl.version}"} %>
CatalogEntry is a through relationship between Issue and Catalog with a lot of additional listing data on each record. This is inside the nested fields partial for catalog_entry, which is called in the parent form:
<%= f.simple_fields_for :catalog_entries do |catalog_entry_form| %>
<%= render "catalog_entry_fields", form: catalog_entry_form %>
<% end %>
I've tried a few different things, including SimpleForm's as: :display
( https://github.com/heartcombo/simple_form/wiki/Create-an-%22input%22-just-for-displaying-attribute-value )custom form type, but they all break the form. Solving this with javascript just seems like the wrong way to do it, since the attribute value is already being passed in.
The Display Input code:
<%= form.association :catalog,
as: :display,
association_label: 'name',
label: false %> Listing
And if association_label
is commented out, it does return an object, e.g. #<Catalog:0x00007fd7829b1098>
. If it is not, it returns undefined method
name' for nil:NilClass`, which is weird, because there is an object there...
The problem is not with
catalog_entry_fields
. When thecatalog_entry_fields
is called at this linethe Catalog object you send it does not have a
category_id
so whenname
is called oncategory_id
it returns nil. If you remove this line, the form displays as expected. You can see this by inspecting theobject
in the customdisplay_input
class.When the
display_input
class is called here:The returned object is
#<CatalogEntry id: nil, catalog_id: 1, issue_id: nil, issue_type_id: nil, category_id: nil, issue_number: nil, variety: nil, combined: nil, event: false, notes: nil, created_at: nil, updated_at: nil, listed_in_error: nil, issueable_id: 5, issueable_type: "Lodge", patchscan_url: nil, slug: nil>
When the
display_input
class is called here:The object returned by the form builder is
#<CatalogEntry id: nil, catalog_id: nil, issue_id: nil, issue_type_id: nil, category_id: nil, issue_number: nil, variety: nil, combined: nil, event: false, notes: nil, created_at: nil, updated_at: nil, listed_in_error: nil, issueable_id: nil, issueable_type: nil, patchscan_url: nil, slug: nil>
there is no catalog_id, soname
is being called on nil which is causing the error.