Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions lib/ransack/helpers/form_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ def search_form_for(record, options = {}, &proc)
form_for(record, options, &proc)
end

# +search_form_with+
#
# <%= search_form_with(model: @q) do |f| %>
#
def search_form_with(record_or_options = {}, options = {}, &proc)
if record_or_options.is_a?(Hash) && record_or_options.key?(:model)
# Called with keyword arguments: search_form_with(model: @q)
options = record_or_options
record = options.delete(:model)
else
# Called with positional arguments: search_form_with(@q)
record = record_or_options
end
search = extract_search_and_set_url(record, options, 'search_form_with')
options[:html] ||= {}
html_options = build_html_options(search, options, :get)
finalize_form_with_options(options, html_options)
form_with(model: search, **options, &proc)
end

# +turbo_search_form_for+
#
# <%= turbo_search_form_for(@q) do |f| %>
Expand Down Expand Up @@ -108,6 +128,12 @@ def finalize_form_options(options, html_options)
options[:builder] ||= FormBuilder
end

def finalize_form_with_options(options, html_options)
options[:scope] ||= Ransack.options[:search_key]
options[:html].reverse_merge!(html_options)
options[:builder] ||= FormBuilder
end

def options_for(record)
record.map { |r| parse_record(r) }
end
Expand Down
74 changes: 74 additions & 0 deletions spec/ransack/helpers/form_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,58 @@ module Helpers
it { should match /example_name_eq/ }
end

describe '#search_form_with with default format' do
subject { @controller.view_context
.search_form_with(model: Person.ransack) {} }
it { should match /action="\/people"/ }
end

describe '#search_form_with with pdf format' do
subject {
@controller.view_context
.search_form_with(model: Person.ransack, format: :pdf) {}
}
it { should match /action="\/people.pdf"/ }
end

describe '#search_form_with with json format' do
subject {
@controller.view_context
.search_form_with(model: Person.ransack, format: :json) {}
}
it { should match /action="\/people.json"/ }
end

describe '#search_form_with with an array of routes' do
subject {
@controller.view_context
.search_form_with(model: [:admin, Comment.ransack]) {}
}
it { should match /action="\/admin\/comments"/ }
end

describe '#search_form_with with custom default search key' do
before do
Ransack.configure { |c| c.search_key = :example }
end
after do
Ransack.configure { |c| c.search_key = :q }
end
subject {
@controller.view_context
.search_form_with(model: Person.ransack) { |f| f.text_field :name_eq }
}
it { should match /example\[name_eq\]/ }
end

describe '#search_form_with without Ransack::Search object' do
it 'raises ArgumentError' do
expect {
@controller.view_context.search_form_with(model: "not a search object") {}
}.to raise_error(ArgumentError, 'No Ransack::Search object was provided to search_form_with!')
end
end

describe '#turbo_search_form_for with default options' do
subject {
@controller.view_context
Expand Down Expand Up @@ -994,6 +1046,28 @@ module Helpers
helper.send(:extract_search_and_set_url, "invalid", options, 'turbo_search_form_for')
}.to raise_error(ArgumentError, 'No Ransack::Search object was provided to turbo_search_form_for!')
end

it 'extracts search from Ransack::Search object for search_form_with' do
options = {}
result = helper.send(:extract_search_and_set_url, search, options, 'search_form_with')
expect(result).to eq(search)
expect(options[:url]).to match(/people/)
end

it 'extracts search from array with Search object for search_form_with' do
options = {}
comment_search = Comment.ransack
result = helper.send(:extract_search_and_set_url, [:admin, comment_search], options, 'search_form_with')
expect(result).to eq(comment_search)
expect(options[:url]).to match(/admin/)
end

it 'raises error for invalid record with correct method name for search_form_with' do
options = {}
expect {
helper.send(:extract_search_and_set_url, "invalid", options, 'search_form_with')
}.to raise_error(ArgumentError, 'No Ransack::Search object was provided to search_form_with!')
end
end
end
end
Expand Down
Loading