activerecord-hackery/ransack · error · ArgumentError
attribute_select must be called inside a search FormBuilder!
Error message
attribute_select must be called inside a search FormBuilder!
What it means
Ransack's FormBuilder#attribute_select (and sort_select, which delegates to it) requires the form's underlying object to be a Ransack::Search — detected by responding to #context. If you use these helpers inside a plain form_for(@record) form, the object is an AR model that does not respond to :context, and this ArgumentError is raised.
Source
Thrown at lib/ransack/helpers/form_builder.rb:51
i18n = options[:i18n] || {}
text ||= object.translate(
method, i18n.reverse_merge(include_associations: true)
) if object.respond_to? :translate
super(method, text, options, &block)
end
def submit(value = nil, options = {})
value, options = nil, value if value.is_a?(Hash)
value ||= Translate.word(:search).titleize
super(value, options)
end
def attribute_select(options = nil, html_options = nil, action = nil)
options ||= {}
html_options ||= {}
action ||= Constants::SEARCH
default = options.delete(:default)
raise ArgumentError, formbuilder_error_message(
"#{action}_select") unless object.respond_to?(:context)
options[:include_blank] = true unless options.has_key?(:include_blank)
bases = [''.freeze].freeze + association_array(options[:associations])
if bases.size > 1
collection = attribute_collection_for_bases(action, bases)
object.name ||= default if can_use_default?(
default, :name, mapped_values(collection.flatten(2))
)
template_grouped_collection_select(collection, options, html_options)
else
collection = collection_for_base(action, bases.first)
object.name ||= default if can_use_default?(
default, :name, mapped_values(collection)
)
template_collection_select(:name, collection, options, html_options)
end
end
View on GitHub (pinned to e82f6bab39)
Solutions
- Build a search object in the controller: @q = Article.ransack(params[:q])
- Use search_form_for @q do |f| (Ransack's helper) so the builder object is the search, then f.attribute_select works
- If the form must stay a plain form_for, replace attribute_select with your own collection_select over Article.ransackable_attributes
Example fix
# controller before: @article = Article.new after: @q = Article.ransack(params[:q]) # view <!-- before --> <%= form_for @article do |f| %> <%= f.attribute_select %> <% end %> <!-- after --> <%= search_form_for @q do |f| %> <%= f.attribute_select %> <% end %>
Defensive patterns
Strategy: type-guard
Type guard
def search_form_builder?(builder) builder.object.respond_to?(:context) # true only for Ransack::Search objects end
Prevention
- Only call attribute_select/sort_select inside search_form_for blocks
- Set a controller before_action that assigns @q = Model.ransack(params[:q]) for every action rendering a search form
- Smoke-test views that mix plain form_for with copied Ransack snippets — they fail only at render time
When it happens
Trigger: <%= form_for @article do |f| %> <%= f.attribute_select %> — attribute_select, f.sort_select, or any 'search_select'/'sort_select' action variant called on a builder bound to a model instance or relation instead of a Ransack::Search.
Common situations: Copy-pasting a Ransack view snippet into an existing form_for block; forgetting to build @q in the controller; using simple_form_for/form_with with a record instead of search_form_for with a search object.
Related errors
- sort_direction must be called inside a search FormBuilder!
- First argument must be a Ransack::Search!
- No Ransack::Search object was provided to #{method_name}!
- #{type} cannot be converted to an ARel join type
- #{value} cannot be converted to a Class
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/a04411a9d7f890e4.
Report an issue: GitHub.