Skip to content

Commit

Permalink
evol:use and for distinct keys and or for the same keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Quent1Pr committed Dec 1, 2021
1 parent c7f907c commit 7c5be0d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
12 changes: 9 additions & 3 deletions lib/rails_admin/adapters/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,21 @@ def query_scope(scope, query, fields = config.list.fields.select(&:queryable?))
# "0055" is the filter index, no use here. o is the operator, v the value
def filter_scope(scope, filters, fields = config.list.fields.select(&:filterable?))
filters.each_pair do |field_name, filters_dump|
field = fields.detect { |f| f.name.to_s == field_name }
multiple_filters_with_same_key = field.searchable_columns.length == 1

wb = WhereBuilder.new(scope) if multiple_filters_with_same_key

filters_dump.each do |_, filter_dump|
wb = WhereBuilder.new(scope)
field = fields.detect { |f| f.name.to_s == field_name }
wb = WhereBuilder.new(scope) unless multiple_filters_with_same_key
value = parse_field_value(field, filter_dump[:v])

wb.add(field, value, (filter_dump[:o] || RailsAdmin::Config.default_search_operator))
# AND current filter statements to other filter statements
scope = wb.build
scope = wb.build unless multiple_filters_with_same_key
end
# OR current filter statements to other filter statements if multiple filters for the same key
scope = wb.build if multiple_filters_with_same_key
end
scope
end
Expand Down
11 changes: 7 additions & 4 deletions lib/rails_admin/adapters/mongoid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,12 @@ def query_scope(scope, query, fields = config.list.fields.select(&:queryable?))
# filters example => {"string_field"=>{"0055"=>{"o"=>"like", "v"=>"test_value"}}, ...}
# "0055" is the filter index, no use here. o is the operator, v the value
def filter_scope(scope, filters, fields = config.list.fields.select(&:filterable?))
statements = []


filters.each_pair do |field_name, filters_dump|
statements = []
field = fields.detect { |f| f.name.to_s == field_name }
filters_dump.each do |_, filter_dump|
field = fields.detect { |f| f.name.to_s == field_name }
next unless field

value = parse_field_value(field, filter_dump[:v])
Expand All @@ -163,9 +164,11 @@ def filter_scope(scope, filters, fields = config.list.fields.select(&:filterable
statements << field_statements.first
end
end
and_or_or = '$and'
and_or_or = '$or' if statements.length > 1 and field.searchable_columns.length == 1
scope = scope.where(statements.any? ? {and_or_or => statements} : {})
end

scope.where(statements.any? ? {'$and' => statements} : {})
scope
end

def parse_collection_name(column)
Expand Down
18 changes: 18 additions & 0 deletions spec/integration/actions/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,24 @@
end
end

it 'allows to query the same attribute with or' do
RailsAdmin.config Player do
list do
field :name
field :team
field :injured
field :retired
end
end

visit index_path(model_name: 'player', f: {name: {'1' => {v: @players[0].name}, '2' => {v: @players[1].name}}})
is_expected.to have_content(@players[0].name)
is_expected.to have_content(@players[1].name)
(2..3).each do |i|
is_expected.to have_no_content(@players[i].name)
end
end

it 'allows to filter on one attribute' do
RailsAdmin.config Player do
list do
Expand Down

0 comments on commit 7c5be0d

Please sign in to comment.