mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Move where grouping into WhereClause
This commit is contained in:
parent
16ce2eecd3
commit
a5fcdae0a0
3 changed files with 59 additions and 11 deletions
|
@ -852,7 +852,7 @@ module ActiveRecord
|
|||
|
||||
build_joins(arel, joins_values.flatten) unless joins_values.empty?
|
||||
|
||||
collapse_wheres(arel, (where_clause.predicates - [''])) #TODO: Add uniq with real value comparison / ignore uniqs that have binds
|
||||
arel.where(where_clause.ast) unless where_clause.empty?
|
||||
|
||||
arel.having(*having_clause.predicates.uniq.reject(&:blank?)) if having_clause.any?
|
||||
|
||||
|
@ -911,16 +911,6 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def collapse_wheres(arel, wheres)
|
||||
predicates = wheres.map do |where|
|
||||
next where if ::Arel::Nodes::Equality === where
|
||||
where = Arel.sql(where) if String === where
|
||||
Arel::Nodes::Grouping.new(where)
|
||||
end
|
||||
|
||||
arel.where(Arel::Nodes::And.new(predicates)) if predicates.present?
|
||||
end
|
||||
|
||||
def association_for_table(table_name)
|
||||
table_name = table_name.to_s
|
||||
@klass._reflect_on_association(table_name) ||
|
||||
|
|
|
@ -53,6 +53,10 @@ module ActiveRecord
|
|||
}.to_h
|
||||
end
|
||||
|
||||
def ast
|
||||
Arel::Nodes::And.new(predicates_with_wrapped_sql_literals)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
other.is_a?(WhereClause) &&
|
||||
predicates == other.predicates &&
|
||||
|
@ -128,6 +132,27 @@ module ActiveRecord
|
|||
columns.include?(column.name)
|
||||
end
|
||||
end
|
||||
|
||||
def predicates_with_wrapped_sql_literals
|
||||
non_empty_predicates.map do |node|
|
||||
if Arel::Nodes::Equality === node
|
||||
node
|
||||
else
|
||||
wrap_sql_literal(node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def non_empty_predicates
|
||||
predicates - ['']
|
||||
end
|
||||
|
||||
def wrap_sql_literal(node)
|
||||
if ::String === node
|
||||
node = Arel.sql(node)
|
||||
end
|
||||
Arel::Nodes::Grouping.new(node)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -111,6 +111,39 @@ class ActiveRecord::Relation
|
|||
assert_equal expected, where_clause.except("id", "name")
|
||||
end
|
||||
|
||||
test "ast groups its predicates with AND" do
|
||||
where_clause = WhereClause.new([
|
||||
table["id"].in([1, 2, 3]),
|
||||
table["name"].eq(bind_param),
|
||||
], [])
|
||||
expected = Arel::Nodes::And.new(where_clause.predicates)
|
||||
|
||||
assert_equal expected, where_clause.ast
|
||||
end
|
||||
|
||||
test "ast wraps any SQL literals in parenthesis" do
|
||||
random_object = Object.new
|
||||
where_clause = WhereClause.new([
|
||||
table["id"].in([1, 2, 3]),
|
||||
"foo = bar",
|
||||
random_object,
|
||||
], [])
|
||||
expected = Arel::Nodes::And.new([
|
||||
table["id"].in([1, 2, 3]),
|
||||
Arel::Nodes::Grouping.new(Arel.sql("foo = bar")),
|
||||
Arel::Nodes::Grouping.new(random_object),
|
||||
])
|
||||
|
||||
assert_equal expected, where_clause.ast
|
||||
end
|
||||
|
||||
test "ast removes any empty strings" do
|
||||
where_clause = WhereClause.new([table["id"].in([1, 2, 3])], [])
|
||||
where_clause_with_empty = WhereClause.new([table["id"].in([1, 2, 3]), ''], [])
|
||||
|
||||
assert_equal where_clause.ast, where_clause_with_empty.ast
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def table
|
||||
|
|
Loading…
Reference in a new issue