1
0
Fork 0
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:
Sean Griffin 2015-01-27 09:41:25 -07:00
parent 16ce2eecd3
commit a5fcdae0a0
3 changed files with 59 additions and 11 deletions

View file

@ -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) ||

View file

@ -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

View file

@ -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