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: method

View on GitHub (pinned to e82f6bab39)

Solutions

  1. Build the search in the controller: @q = Article.ransack(params[:q]) and use search_form_for(@q)
  2. For nested/polymorphic forms, include the search in the array: search_form_for([@article, @q])
  3. 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

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


AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21). Data as JSON: /api/errors/1b470a539ba3c9a3. Report an issue: GitHub.