heartcombo/simple_form · error · ArgumentError
Association cannot be used in forms not associated with an o
Error message
Association cannot be used in forms not associated with an object
What it means
f.association needs the form's @object to read the ActiveRecord reflection, infer the attribute name (e.g. category_id) and fetch the collection. If the builder has no object — as with simple_form_for :search — and no block is given, it raises ArgumentError (lib/simple_form/form_builder.rb:213). With a block it delegates to simple_fields_for instead and never raises.
Source
Thrown at lib/simple_form/form_builder.rb:213
# When a block is given, association simple behaves as a proxy to
# simple_fields_for:
#
# f.association :company do |c|
# c.input :name
# c.input :type
# end
#
# From the options above, only :collection can also be supplied.
#
# Please note that the association helper is currently only tested with Active Record. Depending on the ORM you are using your mileage may vary.
#
def association(association, options = {}, &block)
options = options.dup
return simple_fields_for(*[association,
options.delete(:collection), options].compact, &block) if block_given?
raise ArgumentError, "Association cannot be used in forms not associated with an object" unless @object
reflection = find_association_reflection(association)
raise "Association #{association.inspect} not found" unless reflection
options[:as] ||= :select
options[:collection] ||= fetch_association_collection(reflection, options)
attribute = build_association_attribute(reflection, association, options)
input(attribute, options.merge(reflection: reflection))
end
# Creates a button:
#
# form_for @user do |f|
# f.button :submit
# end
#View on GitHub (pinned to 18f38aad0b)
Solutions
- For object-less forms, replace association with an explicit collection input: f.input :category_id, collection: Category.order(:name)
- Back the form with a real object — a persisted or unsaved record, form object or presenter — so the reflection can be read
- If you want nested fields, pass a block: f.association :category do |c| ... end, which delegates to simple_fields_for and bypasses the check
Example fix
# before <%= simple_form_for :search, method: :get do |f| %> <%= f.association :category %> <!-- ArgumentError: not associated with an object --> <% end %> # after <%= simple_form_for :search, method: :get do |f| %> <%= f.input :category_id, collection: Category.order(:name), label_method: :name, value_method: :id %> <% end %>
Defensive patterns
Strategy: validation
Validate before calling
if f.object.present? f.association :category else f.input :category_id, collection: Category.order(:name) end
Prevention
- Reserve f.association for forms bound to a record instance
- For search/filter forms, use f.input with an explicit :collection
- In shared partials, branch on f.object.present? so both object-backed and object-less forms render
- Set controller instance variables explicitly so simple_form_for @record never receives nil unexpectedly
When it happens
Trigger: simple_form_for :search, method: :get do |f| f.association :category end (symbol form, object is nil); simple_form_for(@search) where @search is nil because the controller never assigned it; any builder whose object is nil calling association without a block.
Common situations: Search/filter forms that only need a dropdown of records; shared form partials reused for both model-backed and object-less forms; controller refactor that stops setting the instance variable the view builds its form from.
Related errors
- :has_one associations are not supported by f.association
- You need to give :to as option to map_type
- A block is required as argument to wrapper
- Couldn't find wrapper with name #{name}
- SimpleForm.include_component expects a module but got: #{com
AI-assisted analysis of heartcombo/simple_form@18f38aad0b (2026-08-21).
Data as JSON: /api/errors/7c4c0fd55acfc4ef.
Report an issue: GitHub.