Spec-Zone.ru › Ruby on Rails 6.1

модуль ActiveRecord::Querying

Публичные методы экземпляра

count_by_sql(sql) Показать исходный код
# File activerecord/lib/active_record/querying.rb, line 83
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-запрос, который должен возвращать количество записей из базы данных, см. пример выше.

find_by_sql(sql, binds = [], preparable: nil, &block) Показать исходный код
# File activerecord/lib/active_record/querying.rb, line 46
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

  unless column_types.empty?
    column_types = column_types.reject { |k, _| attribute_types.key?(k) }
  end

  message_bus = ActiveSupport::Notifications.instrumenter

  payload = {
    record_count: result_set.length,
    class_name: name
  }

  message_bus.instrument("instantiation.active_record", payload) do
    if result_set.includes_column?(inheritance_column)
      result_set.map { |record| instantiate(record, column_types, &block) }
    else
      # Instantiate a homogeneous set
      result_set.map { |record| instantiate_instance_of(self, record, column_types, &block) }
    end
  end
end

Выполняет пользовательский SQL-запрос к базе данных и возвращает все результаты. Результаты будут возвращены в виде массива, где запрошенные столбцы инкапсулированы как атрибуты модели, из которой вы вызываете этот метод. Например, если вы вызовете Product.find_by_sql, то результаты будут возвращены в объекте Product с атрибутами, которые вы указали в SQL-запросе.

Если вы вызываете сложный SQL-запрос, охватывающий несколько таблиц, столбцы, указанные в SELECT, будут атрибутами модели, независимо от того, являются ли они столбцами соответствующей таблицы.

Параметр sql представляет собой полный SQL-запрос в виде строки. Он будет вызван как есть; не будет выполнено никаких баз-данных-независимых преобразований. Это должно быть крайним случаем, потому что использование специфичных для СУБД терминов заблокирует вас использованием конкретной СУБД или потребует изменения вашего вызова при переключении СУБД.

# 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", "author"=>"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–2020 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API