Он пока не получил широкого применения, но я написал следующий код, который, похоже, решает проблему.Эта обезьяна исправляет адаптеры, чтобы иметь метод для его поддержки:
module ActiveRecord
module ConnectionAdapters
class AbstractAdapter
# Will return the given strings as a SQL concationation. By default
# uses the SQL-92 syntax:
#
# concat('foo', 'bar') -> "foo || bar"
def concat(*args)
args * " || "
end
end
class AbstractMysqlAdapter < AbstractAdapter
# Will return the given strings as a SQL concationation.
# Uses MySQL format:
#
# concat('foo', 'bar') -> "CONCAT(foo, bar)"
def concat(*args)
"CONCAT(#{args * ', '})"
end
end
class SQLServerAdapter < AbstractAdapter
# Will return the given strings as a SQL concationation.
# Uses MS-SQL format:
#
# concat('foo', 'bar') -> foo + bar
def concat(*args)
args * ' + '
end
end
end
end
С этим вы сможете сделать следующее в вашем коде:
class User < ActiveRecord::Base
def self.find_by_name(name)
where("#{connection.concat('first_name', 'last_name')} = ?", name)
end
end
Это выведет следующееSQL-запрос к базе данных SQL-92 (Oracle, SQLite, PostgreSQL):
SELECT * FROM users WHERE first_name || last_name = ?
Для MySQL выводится:
SELECT * FROM users WHERE CONCAT(first_name, last_name) = ?
Для SQL Server выводится
SELECT * FROM users WHERE first_name + last_name = ?
Очевидно, что вы можете распространить эту концепцию на другие адаптеры баз данных.