Add ransack! method which raises error if passed unknown condition

This commit is contained in:
Aaron Lipman 2020-06-07 22:15:18 -04:00
parent 150eeb2f08
commit 46de17eba8
No known key found for this signature in database
GPG Key ID: 247BF5E0C15C6050
6 changed files with 79 additions and 3 deletions

View File

@ -1,5 +1,9 @@
# Change Log
* Add `ActiveRecord::Base.ransack!` which raises error if passed unknown condition
*Aaron Lipman*
## 2.4.0 - 2020-11-27
*

View File

@ -670,6 +670,43 @@ Trying it out in `rails console`:
That's it! Now you know how to whitelist/blacklist various elements in Ransack.
### Handling unknown predicates or attributes
By default, Ransack will ignore any unknown predicates or attributes:
```ruby
Article.ransack(unknown_attr_eq: 'Ernie').result.to_sql
=> SELECT "articles".* FROM "articles"
```
Ransack may be configured to raise an error if passed an unknown predicate or
attributes, by setting the `ignore_unknown_conditions` option to `false` in your
Ransack initializer file at `config/initializers/ransack.rb`:
```ruby
Ransack.configure do |c|
# Raise errors if a query contains an unknown predicate or attribute.
# Default is true (do not raise error on unknown conditions).
c.ignore_unknown_conditions = false
end
```
```ruby
Article.ransack(unknown_attr_eq: 'Ernie')
# ArgumentError (Invalid search term unknown_attr_eq)
```
As an alternative to setting a global configuration option, the `.ransack!`
class method also raises an error if passed an unknown condition:
```ruby
Article.ransack!(unknown_attr_eq: 'Ernie')
# ArgumentError: Invalid search term unknown_attr_eq
```
This is equivilent to the `ignore_unknown_conditions` configuration option,
except it may be applied on a case-by-case basis.
### Using Scopes/Class Methods
Continuing on from the preceding section, searching by scopes requires defining

View File

@ -18,6 +18,10 @@ module Ransack
Search.new(self, params, options)
end
def ransack!(params = {}, options = {})
ransack(params, options.merge(ignore_unknown_conditions: false))
end
def ransacker(name, opts = {}, &block)
self._ransackers = _ransackers.merge name.to_s => Ransacker
.new(self, name, opts, &block)

View File

@ -30,6 +30,7 @@ module Ransack
)
@scope_args = {}
@sorts ||= []
@ignore_unknown_conditions = options[:ignore_unknown_conditions] == false ? false : true
build(params.with_indifferent_access)
end
@ -45,7 +46,7 @@ module Ransack
base.send("#{key}=", value)
elsif @context.ransackable_scope?(key, @context.object)
add_scope(key, value)
elsif !Ransack.options[:ignore_unknown_conditions]
elsif !Ransack.options[:ignore_unknown_conditions] || !@ignore_unknown_conditions
raise ArgumentError, "Invalid search term #{key}"
end
end

View File

@ -122,6 +122,10 @@ module Ransack
expect { Person.ransack('') }.to_not raise_error
end
it 'raises exception if ransack! called with unknown condition' do
expect { Person.ransack!(unknown_attr_eq: 'Ernie') }.to raise_error
end
it 'does not modify the parameters' do
params = { name_eq: '' }
expect { Person.ransack(params) }.not_to change { params }

View File

@ -232,7 +232,7 @@ module Ransack
context 'with an invalid condition' do
subject { Search.new(Person, unknown_attr_eq: 'Ernie') }
context 'when ignore_unknown_conditions is false' do
context 'when ignore_unknown_conditions configuration option is false' do
before do
Ransack.configure { |c| c.ignore_unknown_conditions = false }
end
@ -240,13 +240,39 @@ module Ransack
specify { expect { subject }.to raise_error ArgumentError }
end
context 'when ignore_unknown_conditions is true' do
context 'when ignore_unknown_conditions configuration option is true' do
before do
Ransack.configure { |c| c.ignore_unknown_conditions = true }
end
specify { expect { subject }.not_to raise_error }
end
subject(:with_ignore_unknown_conditions_false) {
Search.new(Person,
{ unknown_attr_eq: 'Ernie' },
{ ignore_unknown_conditions: false }
)
}
subject(:with_ignore_unknown_conditions_true) {
Search.new(Person,
{ unknown_attr_eq: 'Ernie' },
{ ignore_unknown_conditions: true }
)
}
context 'when ignore_unknown_conditions search parameter is absent' do
specify { expect { subject }.not_to raise_error }
end
context 'when ignore_unknown_conditions search parameter is false' do
specify { expect { with_ignore_unknown_conditions_false }.to raise_error ArgumentError }
end
context 'when ignore_unknown_conditions search parameter is true' do
specify { expect { with_ignore_unknown_conditions_true }.not_to raise_error }
end
end
it 'does not modify the parameters' do