Skip to content

Commit

Permalink
Add ransack! method which raises error if passed unknown condition
Browse files Browse the repository at this point in the history
  • Loading branch information
alipman88 committed Dec 13, 2020
1 parent 150eeb2 commit 7ee824a
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

*
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ else
gem 'actionpack'
end
end
gem 'mysql2', '~> 0.5.2'
# gem 'mysql2', '~> 0.5.2'

group :test do
gem 'machinist', '~> 1.0.6'
Expand Down
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lib/ransack/adapters/active_record/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def ransack(params = {}, options = {})
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)
Expand Down
3 changes: 2 additions & 1 deletion lib/ransack/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def initialize(object, params = {}, options = {})
)
@scope_args = {}
@sorts ||= []
@ignore_unknown_conditions = options[:ignore_unknown_conditions] == false ? false : true
build(params.with_indifferent_access)
end

Expand All @@ -45,7 +46,7 @@ def build(params)
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
Expand Down
4 changes: 4 additions & 0 deletions spec/ransack/adapters/active_record/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ module ActiveRecord
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 }
Expand Down
30 changes: 28 additions & 2 deletions spec/ransack/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -232,21 +232,47 @@ 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

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
Expand Down

0 comments on commit 7ee824a

Please sign in to comment.