Add feature to all selectively skipping scope argument sanitization.

Fixed copy issues
This commit is contained in:
Justin Hirsch 2018-07-17 09:18:28 -07:00
parent 1d1c64b470
commit 24a4d4330a
6 changed files with 57 additions and 2 deletions

View File

@ -1,5 +1,10 @@
# Change Log
* Add the ability to skip arg sanitization on a per scope basis. Using
`ransackable_scopes_skip_sanitize_args`, users can define a list of
scopes which will bypass parameter sanitization. This allows passing 0,
1, t, f, etc. to a scope as an actual parameter.
## Version 1.8.8 - 2018-03-16
* Fix multiple database support
PR [#893](https://github.com/activerecord-hackery/ransack/pull/893)

View File

@ -734,7 +734,7 @@ boolean. This is currently resolved in Rails 5 :smiley:
However, perhaps you have `user_id: [1]` and you do not want Ransack to convert
1 into a boolean. (Values sanitized to booleans can be found in the
[constants.rb](https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/constants.rb#L28)).
To turn this off, and handle type conversions yourself, set
To turn this off globally, and handle type conversions yourself, set
`sanitize_custom_scope_booleans` to false in an initializer file like
config/initializers/ransack.rb:
@ -744,6 +744,19 @@ Ransack.configure do |c|
end
```
To turn this off on a per-scope basis Ransack adds the following method to
`ActiveRecord::Base` that you can redefine to selectively override sanitization:
`ransackable_scopes_skip_sanitize_args`
Add the scope you wish to bypass this behavior to ransackable_scopes_skip_sanitize_args:
```ruby
def ransackable_scopes_skip_sanitize_args
[:scope_to_skip_sanitize_args]
end
```
Scopes are a recent addition to Ransack and currently have a few caveats:
First, a scope involving child associations needs to be defined in the parent
table model, not in the child model. Second, scopes with an array as an

View File

@ -64,6 +64,14 @@ module Ransack
[]
end
# ransack_scope_skip_sanitize_args, by default, returns an empty array.
# i.e. use the sanitize_scope_args setting to determin if args should be converted.
# For overriding with a list of scopes which should be passed the args as-is.
#
def ransackable_scopes_skip_sanitize_args
[]
end
end
end
end

View File

@ -138,6 +138,10 @@ module Ransack
klass.ransackable_scopes(auth_object).any? { |s| s.to_sym == str.to_sym }
end
def ransackable_scope_skip_sanitize_args?(str, klass)
klass.ransackable_scopes_skip_sanitize_args.any? { |s| s.to_sym == str.to_sym }
end
def searchable_attributes(str = ''.freeze)
traverse(str).ransackable_attributes(auth_object)
end

View File

@ -123,7 +123,7 @@ module Ransack
private
def add_scope(key, args)
sanitized_args = if Ransack.options[:sanitize_scope_args]
sanitized_args = if Ransack.options[:sanitize_scope_args] && !@context.ransackable_scope_skip_sanitize_args?(key, @context.object)
sanitized_scope_args(args)
else
args

View File

@ -97,6 +97,25 @@ module Ransack
expect(s.result.to_sql).to (include 'age > 0')
end
end
context "with ransackable_scopes_skip_sanitize_args enabled for scope" do
before do
allow(Person)
.to receive(:ransackable_scopes_skip_sanitize_args)
.and_return([:over_age])
end
it 'passes true values to scopes' do
s = Person.ransack('over_age' => 1)
expect(s.result.to_sql).to (include 'age > 1')
end
it 'passes false values to scopes' do
s = Person.ransack('over_age' => 0)
expect(s.result.to_sql).to (include 'age > 0')
end
end
end
it 'does not raise exception for string :params argument' do
@ -645,6 +664,12 @@ module Ransack
it { should eq [] }
end
describe '#ransackable_scopes_skip_sanitize_args' do
subject { Person.ransackable_scopes_skip_sanitize_args }
it { should eq [] }
end
end
end
end