Skip to content

Commit a402a20

Browse files
committed
Fix nested condition
1 parent e06a27d commit a402a20

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

lib/ransack/adapters/active_record/context.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,14 @@ def extract_correlated_key(join_root)
201201
nil
202202
end
203203
when Arel::Nodes::And
204-
extract_correlated_key(join_root.left) || extract_correlated_key(join_root.right)
204+
if join_root.children.any?
205+
join_root.children.each do |child|
206+
eck = extract_correlated_key(child)
207+
return eck unless eck.nil?
208+
end
209+
else
210+
extract_correlated_key(join_root.left) || extract_correlated_key(join_root.right)
211+
end
205212
else
206213
# eg parent was Arel::Nodes::And and the evaluated side was one of
207214
# Arel::Nodes::Grouping or MultiTenant::TenantEnforcementClause

lib/ransack/nodes/condition.rb

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ def formatted_values_for_attribute(attr)
235235
val = attr.ransacker.formatter.call(val)
236236
end
237237
val = predicate.format(val)
238+
if val.is_a?(String) && (val.starts_with?('%') || val.ends_with?('%'))
239+
val = Arel::Nodes::Quoted.new(val)
240+
end
238241
val
239242
end
240243
if predicate.wants_array
@@ -288,12 +291,24 @@ def negative?
288291
def arel_predicate
289292
predicate = attributes.map { |attribute|
290293
association = attribute.parent
291-
if negative? && attribute.associated_collection?
294+
parent_table = association.table
295+
296+
if negative? && attribute.associated_collection? && not_nested_condition(attribute, parent_table)
292297
query = context.build_correlated_subquery(association)
293298
context.remove_association(association)
294-
if self.predicate_name == 'not_null' && self.value
295-
query.where(format_predicate(attribute))
296-
Arel::Nodes::In.new(context.primary_key, Arel.sql(query.to_sql))
299+
300+
case self.predicate_name
301+
when 'not_null'
302+
if self.value
303+
query.where(format_predicate(attribute))
304+
Arel::Nodes::In.new(context.primary_key, Arel.sql(query.to_sql))
305+
else
306+
query.where(format_predicate(attribute).not)
307+
Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql))
308+
end
309+
when 'not_cont'
310+
query.where(attribute.attr.matches(formatted_values_for_attribute(attribute)))
311+
Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql))
297312
else
298313
query.where(format_predicate(attribute).not)
299314
Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql))
@@ -304,10 +319,6 @@ def arel_predicate
304319
}.reduce(combinator_method)
305320

306321
if replace_right_node?(predicate)
307-
# Replace right node object to plain integer value in order to avoid
308-
# ActiveModel::RangeError from Arel::Node::Casted.
309-
# The error can be ignored here because RDBMSs accept large numbers
310-
# in condition clauses.
311322
plain_value = predicate.right.value
312323
predicate.right = plain_value
313324
end
@@ -317,6 +328,10 @@ def arel_predicate
317328

318329
private
319330

331+
def not_nested_condition(attribute, parent_table)
332+
parent_table.class != Arel::Nodes::TableAlias && attribute.name.starts_with?(parent_table.name)
333+
end
334+
320335
def combinator_method
321336
combinator === Constants::OR ? :or : :and
322337
end

0 commit comments

Comments
 (0)