跳至内容 跳至搜索
方法
A
C
F

实例公共方法

async_count_by_sql(sql)

#count_by_sql 相同,但异步执行查询并返回 ActiveRecord::Promise

# File activerecord/lib/active_record/querying.rb, line 106
def async_count_by_sql(sql)
  connection.select_value(sanitize_sql(sql), "#{name} Count", async: true).then(&:to_i)
end

async_find_by_sql(sql, binds = [], preparable: nil, &block)

#find_by_sql 相同,但异步执行查询并返回 ActiveRecord::Promise

# File activerecord/lib/active_record/querying.rb, line 55
def async_find_by_sql(sql, binds = [], preparable: nil, &block)
  _query_by_sql(sql, binds, preparable: preparable, async: true).then do |result|
    _load_from_sql(result, &block)
  end
end

count_by_sql(sql)

返回 SQL 语句的结果,该语句应仅在 SELECT 部分包含 COUNT(*)。此方法的使用应仅限于无法使用 ActiveRecord::Calculations 类方法执行的复杂 SQL 查询。在使用此方法之前先查看这些方法,因为它可能会将你锁定到特定的数据库引擎或需要代码更改才能切换数据库引擎。

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 101
def count_by_sql(sql)
  connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
end

find_by_sql(sql, binds = [], preparable: nil, &block)

针对数据库执行自定义 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 }]

请注意,从用户输入中构建自己的 SQL 查询字符串可能会使你的应用程序面临注入攻击(guides.rubyonrails.org/security.html#sql-injection)。

# File activerecord/lib/active_record/querying.rb, line 50
def find_by_sql(sql, binds = [], preparable: nil, &block)
  _load_from_sql(_query_by_sql(sql, binds, preparable: preparable), &block)
end