如何在 Rails 中链接原始 SQL 查询或如何从 Rails 中的原始 SQL 查询返回 ActiveRecord_Relation?

Posted

技术标签:

【中文标题】如何在 Rails 中链接原始 SQL 查询或如何从 Rails 中的原始 SQL 查询返回 ActiveRecord_Relation?【英文标题】:How to chain raw SQL queries in Rails OR how to return an ActiveRecord_Relation from a raw SQL query in Rails? 【发布时间】:2018-06-02 07:08:28 【问题描述】:

如何运行原始 sql 查询并返回 ActiveRecord_Relation 实例?

在 sqlite3 db 和 Rails 4.2 上,ActiveRecords::Base.exec_query(sql) 返回一个 ActiveRecord_Result 实例。 ActiveRecords::Base.execute(sql) 返回一个数组。这很麻烦,因为我无法对返回的对象运行后续的“ActiveRecord 查询”或原始 sql 查询。

更一般地说,我想知道如何在 Rails 中链接“复杂”的 sql 查询。复杂是指我无法通过 ActiveRecords 提供的“ORM 方法”找到一种方法。通过链接,我的意思是出于性能原因,我想将其分解为几个 SQL 查询。示例:我只想运行一次大而重的第一个 SQL 查询,存储结果,然后根据用户行为运行轻量级的 sql 查询。

我目前正在尝试通过使用服务器端处理实现的dataTables 优化数据库可视化。每次用户与表交互时,服务器都必须运行一个不必要的复杂 SQL 查询,因为我无法将其分解为更简单的查询。我查看了以下问题,但找不到令人满意的解决方案:

Rails raw SQL example

Convert Array#select to active record query in rails 4

Hash/Array to Active Record

【问题讨论】:

你是怎么解决的? 【参考方案1】:

这是一种从 raw_sql 获取 ActiveRecord_Relation 的方法。 如果您确实有一个与您要检索的字段匹配的模型,则效果最好,但正如您在 test_attribute 中看到的那样,任何数据都将被加载。

# Just an example query, any query should be ok
query = <<-SQL
  SELECT *, TRUE AS test_attribute
  FROM users
  WHERE sign_in_count < 10
SQL
relation = User.select('*').from("(#query) AS users")

relation.class
# User::ActiveRecord_Relation

relation.first.test_attribute
# true

【讨论】:

哇,这为我提供了一种将返回数组的 find_by_sql 函数转换为活动记录关系的绝佳方法。如果可能的话,我会 x10 这个。 我收到此错误(对象不支持#inspect)在 Postgres 中不可能吗?谢谢! @ShilpiAgrawal 这是在 postgres 中编写和工作的,是的,你的错误显然与 sql 无关......

以上是关于如何在 Rails 中链接原始 SQL 查询或如何从 Rails 中的原始 SQL 查询返回 ActiveRecord_Relation?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 order rails 查询中修复 sql 注入

如何在rails中使用动态绑定执行原始更新sql

Bookshelfjs ORM 如何获取或查看其构建的 SQL 语句

Rails:将复杂的 SQL 查询转换为 Arel 或 ActiveRecord

如何显示在 Rails 控制台中运行的 SQL 查询?

Laravel 查询构建器 - 如何按别名分组,或进行原始 groupBy