модуль ActiveRecord::Querying
Открытые методы экземпляра
# File activerecord/lib/active_record/querying.rb, line 67
def count_by_sql(sql)
connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
end Возвращает результат SQL-запроса, который должен содержать только COUNT(*) в части SELECT. Использование этого метода должно быть ограничено сложными SQL-запросами, которые нельзя выполнить с помощью методов класса ActiveRecord::Calculations. Посмотрите на них перед использованием этого.
Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id" # => 12
Параметры
-
sql- SQL-запрос, который должен возвращать подсчет из базы данных, см. пример выше.
# File activerecord/lib/active_record/querying.rb, line 40
def find_by_sql(sql, binds = [], preparable: nil, &block)
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
column_types = result_set.column_types.dup
cached_columns_hash = connection.schema_cache.columns_hash(table_name)
cached_columns_hash.each_key { |k| column_types.delete k }
message_bus = ActiveSupport::Notifications.instrumenter
payload = {
record_count: result_set.length,
class_name: name
}
message_bus.instrument("instantiation.active_record", payload) do
result_set.map { |record| instantiate(record, column_types, &block) }
end
end Выполняет пользовательский SQL-запрос к базе данных и возвращает все результаты. Результаты будут возвращены в виде массива, где столбцы, запрошенные в SELECT, будут упакованы в атрибуты модели, из которой вы вызываете этот метод. Если вы вызываете Product.find_by_sql , то результаты будут возвращены в объекте Product с атрибутами, указанными в SQL-запросе.
Если вы вызываете сложный SQL-запрос, охватывающий несколько таблиц, столбцы, указанные в SELECT, будут атрибутами модели, независимо от того, являются ли они столбцами соответствующей таблицы.
Параметр sql представляет собой полный SQL-запрос в виде строки. Он будет вызван как есть, никаких баз данных-независимых преобразований не будет выполнено. Это должно быть крайнее средство, поскольку использование, например, MySQL-специфичных терминов заблокирует вас использованием конкретного движка базы данных или потребует изменения вашего вызова при переключении движков.
# A simple SQL query spanning multiple tables
Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
# => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
Вы можете использовать те же методы подстановки строк, что и с ActiveRecord::QueryMethods#where:
Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.