activerecord-hackery/ransack · error · ArgumentError
No Ransack::Search object was provided to #{method_name}!
Error message
No Ransack::Search object was provided to #{method_name}! What it means
search_form_for (and turbo_search_form_for) call extract_search_and_set_url, which accepts either a Ransack::Search or an array containing one (for polymorphic routing). If the record argument is neither — e.g. an ActiveRecord::Relation, a model instance, or nil — this ArgumentError naming the helper method is raised, because the helper cannot derive the form's URL class or fields without a search.
Source
Thrown at lib/ransack/helpers/form_helper.rb:103
end
private
def extract_search_and_set_url(record, options, method_name)
if record.is_a? Ransack::Search
search = record
options[:url] ||= polymorphic_path(
search.klass, format: options.delete(:format)
)
search
elsif record.is_a?(Array) &&
(search = record.detect { |o| o.is_a?(Ransack::Search) })
options[:url] ||= polymorphic_path(
options_for(record), format: options.delete(:format)
)
search
else
raise ArgumentError,
"No Ransack::Search object was provided to #{method_name}!"
end
end
def build_turbo_options(options)
data_options = {}
if options[:turbo_frame]
data_options[:turbo_frame] = options.delete(:turbo_frame)
end
data_options[:turbo_action] = options.delete(:turbo_action) || 'advance'
{ data: data_options }
end
def build_html_options(search, options, method)
{
class: html_option_for(options[:class], search),
id: html_option_for(options[:id], search),
method: methodView on GitHub (pinned to e82f6bab39)
Solutions
- Build the search in the controller: @q = Article.ransack(params[:q]) and use search_form_for(@q)
- For nested/polymorphic forms, include the search in the array: search_form_for([@article, @q])
- If a plain model form is truly wanted, use form_for/form_with instead of search_form_for
Example fix
# controller # before def index @articles = Article.all end # after def index @q = Article.ransack(params[:q]) @articles = @q.result.includes(:comments) end # view <%= search_form_for @q do |f| %> ... <% end %>
Defensive patterns
Strategy: type-guard
Validate before calling
# controller: make the search unconditional before the view renders def index @q = Article.ransack(params[:q]) end
Type guard
def search_or_array_with_search?(record)
record.is_a?(Ransack::Search) ||
(record.is_a?(Array) && record.any? { |o| o.is_a?(Ransack::Search) })
end Prevention
- search_form_for's first argument is always the search object — never a relation or model instance
- For nested resources use [@parent, @q] so polymorphic_path can route and the search is still present
- Add a view spec for each search form to catch wrong record types at CI time
When it happens
Trigger: search_form_for(@articles) where @articles = Article.all (a Relation); search_form_for(@article) (an instance); search_form_for([@article, Comment.new]) where the array contains no Ransack::Search; turbo_search_form_for(@people) with a relation.
Common situations: Converting an existing index view from form_for(@articles) to Ransack and only renaming the helper; forgetting the controller's @q assignment; nested-resource forms where the author forgot to include the search object in the array.
Related errors
- #{type} cannot be converted to an ARel join type
- #{value} cannot be converted to a Class
- Don't know what context to use for #{object}
- attribute_select must be called inside a search FormBuilder!
- First argument must be a Ransack::Search!
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/1b470a539ba3c9a3.
Report an issue: GitHub.