From 9abd35744fc40ff200a0e2cd589a0cb0450baabb Mon Sep 17 00:00:00 2001 From: Yaroslav Barkovskiy Date: Fri, 26 Feb 2021 11:38:22 +0300 Subject: [PATCH] Add the ability to disable whitespace stripping for string searches --- README.md | 19 ++++++++++++-- lib/ransack/configuration.rb | 16 +++++++++++- lib/ransack/search.rb | 3 ++- spec/ransack/configuration_spec.rb | 14 +++++++++++ spec/ransack/search_spec.rb | 40 +++++++++++++++++++++++++++--- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d6d9c0a99..d5dbd0447 100644 --- a/README.md +++ b/README.md @@ -71,13 +71,15 @@ def index end ``` -##### Default search parameter +##### Default search options + +**Search parameter** Ransack uses a default `:q` param key for search params. This may be changed by setting the `search_key` option in a Ransack initializer file (typically `config/initializers/ransack.rb`): -``` +```ruby Ransack.configure do |c| # Change default search parameter key name. # Default key name is :q @@ -85,6 +87,19 @@ Ransack.configure do |c| end ``` +**String search** + +After version 2.4.0 when searching a string query Ransack by default strips all whitespace around the query string. +This may be disabled by setting the `strip_whitespace` option in a Ransack initializer file: + +```ruby +Ransack.configure do |c| + # Change whitespace stripping behaviour. + # Default is true + c.strip_whitespace = false +end +``` + #### In your view The two primary Ransack view helpers are `search_form_for` and `sort_link`, diff --git a/lib/ransack/configuration.rb b/lib/ransack/configuration.rb index 9a77b6acf..4347db535 100644 --- a/lib/ransack/configuration.rb +++ b/lib/ransack/configuration.rb @@ -34,7 +34,8 @@ def []=(key, value) :down_arrow => '▲'.freeze, :default_arrow => nil, :sanitize_scope_args => true, - :postgres_fields_sort_option => nil + :postgres_fields_sort_option => nil, + :strip_whitespace => true } def configure @@ -170,6 +171,19 @@ def hide_sort_order_indicators=(boolean) self.options[:hide_sort_order_indicators] = boolean end + # By default, Ransack displays strips all whitespace when searching for a string. + # The default may be globally changed in an initializer file like + # `config/initializers/ransack.rb` as follows: + # + # Ransack.configure do |config| + # # Enable whitespace stripping for string searches + # config.strip_whitespace = true + # end + # + def strip_whitespace=(boolean) + self.options[:strip_whitespace] = boolean + end + def arel_predicate_with_suffix(arel_predicate, suffix) if arel_predicate === Proc proc { |v| "#{arel_predicate.call(v)}#{suffix}" } diff --git a/lib/ransack/search.rb b/lib/ransack/search.rb index 35ca06539..b8c1ab6c2 100644 --- a/lib/ransack/search.rb +++ b/lib/ransack/search.rb @@ -15,10 +15,11 @@ class Search :translate, :to => :base def initialize(object, params = {}, options = {}) + strip_whitespace = options.fetch(:strip_whitespace, Ransack.options[:strip_whitespace]) params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h) if params.is_a? Hash params = params.dup - params = params.transform_values { |v| v.is_a?(String) ? v.strip : v } + params = params.transform_values { |v| v.is_a?(String) && strip_whitespace ? v.strip : v } params.delete_if { |k, v| [*v].all?{ |i| i.blank? && i != false } } else params = {} diff --git a/spec/ransack/configuration_spec.rb b/spec/ransack/configuration_spec.rb index 220f213b5..1eba07485 100644 --- a/spec/ransack/configuration_spec.rb +++ b/spec/ransack/configuration_spec.rb @@ -45,6 +45,20 @@ module Ransack Ransack.options = default end + it 'should have default value for strip_whitespace' do + expect(Ransack.options[:strip_whitespace]).to eq true + end + + it 'changes default search key parameter' do + default = Ransack.options.clone + + Ransack.configure { |c| c.strip_whitespace = false } + + expect(Ransack.options[:strip_whitespace]).to eq false + + Ransack.options = default + end + it 'should have default values for arrows' do expect(Ransack.options[:up_arrow]).to eq '▼' expect(Ransack.options[:down_arrow]).to eq '▲' diff --git a/spec/ransack/search_spec.rb b/spec/ransack/search_spec.rb index 15f47b6e0..e66c2e5ba 100644 --- a/spec/ransack/search_spec.rb +++ b/spec/ransack/search_spec.rb @@ -20,10 +20,42 @@ module Ransack Search.new(Person, name_eq: 'foobar') end - it 'strip leading & trailing whitespace before building' do - expect_any_instance_of(Search).to receive(:build) - .with({ 'name_eq' => 'foobar' }) - Search.new(Person, name_eq: ' foobar ') + context 'whitespace stripping' do + context 'when whitespace_strip option is true' do + before do + Ransack.configure { |c| c.strip_whitespace = true } + end + + it 'strips leading & trailing whitespace before building' do + expect_any_instance_of(Search).to receive(:build) + .with({ 'name_eq' => 'foobar' }) + Search.new(Person, name_eq: ' foobar ') + end + end + + context 'when whitespace_strip option is false' do + before do + Ransack.configure { |c| c.strip_whitespace = false } + end + + it 'doesn\'t strip leading & trailing whitespace before building' do + expect_any_instance_of(Search).to receive(:build) + .with({ 'name_eq' => ' foobar ' }) + Search.new(Person, name_eq: ' foobar ') + end + end + + it 'strips leading & trailing whitespace when strip_whitespace search parameter is true' do + expect_any_instance_of(Search).to receive(:build) + .with({ 'name_eq' => 'foobar' }) + Search.new(Person, { name_eq: ' foobar ' }, { strip_whitespace: true }) + end + + it 'doesn\'t strip leading & trailing whitespace when strip_whitespace search parameter is false' do + expect_any_instance_of(Search).to receive(:build) + .with({ 'name_eq' => ' foobar ' }) + Search.new(Person, { name_eq: ' foobar ' }, { strip_whitespace: false }) + end end it 'removes empty suffixed conditions before building' do