Skip to content

Make search_form_* helpers honour per-search search_key (#1118)#1676

Open
ryoya1122 wants to merge 1 commit into
activerecord-hackery:v5.0.0from
ryoya1122:fix/issue-1118-search-form-search-key
Open

Make search_form_* helpers honour per-search search_key (#1118)#1676
ryoya1122 wants to merge 1 commit into
activerecord-hackery:v5.0.0from
ryoya1122:fix/issue-1118-search-form-search-key

Conversation

@ryoya1122

Copy link
Copy Markdown
Contributor

Closes #1118.

Problem

When a search_key: is passed to Model.ransack, the form-building helpers ignore it. The inputs are emitted under the global default key (q[...]) regardless of the override:

q = Person.ransack({}, search_key: :people_search)
search_form_for(q) { |f| f.text_field :name_eq }
# => <input type="text" name="q[name_eq]" id="q_name_eq" />
#                       ^^^ should be people_search[name_eq] / people_search_name_eq

The same applies to search_form_with and turbo_search_form_for. sort_link and sort_url already read the key from the search's context, so the form path is the outlier.

Cause

The two private finalisers used the global default instead of asking the search:

def finalize_form_options(options, html_options)
  options[:as] ||= Ransack.options[:search_key]   # <- global, ignores per-search override
  ...
end

def finalize_form_with_options(options, html_options)
  options[:scope] ||= Ransack.options[:search_key] # <- same
  ...
end

The reporter linked both lines in #1118.

Fix

finalize_form_options / finalize_form_with_options now take the search and read search.context.search_key, the same source sort_link / sort_url already use (see lib/ransack/helpers/form_helper.rb#L200 and #L249).

Context#search_key is initialised as options[:search_key] || Ransack.options[:search_key], so the global default still applies when no per-search override is given.

Compatibility

Model.ransack call Before After
Person.ransack(...) inputs under q[...] (global default) inputs under q[...] (unchanged)
Person.ransack(...) after Ransack.configure { ... :example } inputs under example[...] (global) inputs under example[...] (unchanged)
Person.ransack(..., search_key: :people_search) inputs under q[...] ❌ (#1118) inputs under people_search[...]
options[:as] / options[:scope] explicitly set by caller wins via `

The finalize_form_* methods are private, so the signature change is internal.

Tests

Two new specs in spec/ransack/helpers/form_helper_spec.rb, alongside the existing global-default tests, both red before the fix and green after:

  • #search_form_for with per-search search_key -> expects people_search_name_eq
  • #search_form_with with per-search search_key -> expects people_search[name_eq]

Full suite: 514 examples, 0 failures, 1 pending on v5.0.0 + this branch (SQLite, ActiveRecord 7.2.3.1, Ruby 3.4.9).

Targets v5.0.0 per #1640.

…h search_key (activerecord-hackery#1118)

`sort_link` and `sort_url` already read the search key from the
search's context (`search.context.search_key`). The form-building
helpers were instead falling back to the global `Ransack.options[:search_key]`
in `finalize_form_options` / `finalize_form_with_options`, which meant
that passing `search_key:` to `Model.ransack` was silently ignored:
inputs were emitted under `q[...]` regardless of the override.

The two private finalisers now take the `search` object and use
`search.context.search_key`. `Context#search_key` already falls back
to `Ransack.options[:search_key]` when no per-search override is given,
so the global default continues to apply for the unconfigured case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant