diff options
author | Edward Paget <edward@cassetteta.pe> | 2015-01-14 12:23:37 -0600 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2015-12-17 12:49:50 -0700 |
commit | f726dbe0802395aabf9cc99fe34bc69b375bf344 (patch) | |
tree | 984b5c89c8dc9164c373c13326597ffeeb6f67e1 | |
parent | dad0e081c4dc9dbbcdb195ff4e7f9ad4d2bc6de3 (diff) | |
download | rails-f726dbe0802395aabf9cc99fe34bc69b375bf344.tar.gz rails-f726dbe0802395aabf9cc99fe34bc69b375bf344.tar.bz2 rails-f726dbe0802395aabf9cc99fe34bc69b375bf344.zip |
Delegate to Connection Visitor in WhereSQL Visitor
The WhereSQL visitor always uses the generic ToSQL visitor to create
the where clause sql statement. This means that it'll miss database
specific statements, such as 'ILIKE' in PostgreSQL. Since the
`#where_sql` method is mainly used for ActiveRecord error reporting,
this discrepancy could be confusing to users.
This patch changes the WhereSQL visitor to use the its connection
visitor to generate SQL for each statement in the SelectManager's wheres
array. Then lets them be joined together with ' AND '.
-rw-r--r-- | lib/arel/visitors/where_sql.rb | 6 | ||||
-rw-r--r-- | test/test_select_manager.rb | 21 |
2 files changed, 26 insertions, 1 deletions
diff --git a/lib/arel/visitors/where_sql.rb b/lib/arel/visitors/where_sql.rb index afde15a6c5..80797205c9 100644 --- a/lib/arel/visitors/where_sql.rb +++ b/lib/arel/visitors/where_sql.rb @@ -5,7 +5,11 @@ module Arel def visit_Arel_Nodes_SelectCore o, collector collector << "WHERE " - inject_join o.wheres, collector, ' AND ' + wheres = o.wheres.map do |where| + Nodes::SqlLiteral.new(@connection.visitor.accept(where, collector.class.new).value) + end + + inject_join wheres, collector, ' AND ' end end end diff --git a/test/test_select_manager.rb b/test/test_select_manager.rb index 8425cee031..e6b13e748d 100644 --- a/test/test_select_manager.rb +++ b/test/test_select_manager.rb @@ -968,6 +968,27 @@ module Arel manager.where_sql.must_be_like %{ WHERE "users"."id" = 10 } end + it 'joins wheres with AND' do + table = Table.new :users + manager = Arel::SelectManager.new + manager.from table + manager.where table[:id].eq 10 + manager.where table[:id].eq 11 + manager.where_sql.must_be_like %{ WHERE "users"."id" = 10 AND "users"."id" = 11} + end + + it 'handles database specific statements' do + old_visitor = Table.engine.connection.visitor + Table.engine.connection.visitor = Visitors::PostgreSQL.new Table.engine.connection + table = Table.new :users + manager = Arel::SelectManager.new + manager.from table + manager.where table[:id].eq 10 + manager.where table[:name].matches 'foo%' + manager.where_sql.must_be_like %{ WHERE "users"."id" = 10 AND "users"."name" ILIKE 'foo%' } + Table.engine.connection.visitor = old_visitor + end + it 'returns nil when there are no wheres' do table = Table.new :users manager = Arel::SelectManager.new |