出于与问题无关的原因,我不得不手动构建一个相当复杂的查询,而不是使用ActiveRecord.该查询当前返回一个PostgreSQL数组数据类型,我正在try 将其映射到比Rails默认提供的类型更有用的Ruby类型.

伪代码如下:

SELECT
  ARRAY_AGG(u.id) AS awesome_data
FROM u
GROUP BY condition
records = []
ActiveRecord::Base.connection.select_all(
      ActiveRecord::Base.send(:sanitize_sql_array, [
                                query,
        # parameters
                              ])
      ).each do |record|
        records << record
      end

这个查询运行得很好,返回了我所期望的结果,但是awesome_data列的类型返回为string,并且包含类似{1,2,3,4}的值.

几个问题:

  • 有什么方法可以让Rails理解该列是数组类型并将其解析为数组吗?
  • 有没有什么实用方法可以帮我把它解析成一个整数数组?
  • 我必须自己解析这个值吗?

限制:

我们必须假设有必要以这种方式查询数据库,而不是通过ActiveRecord.

环境:rails 6.1、Ruby 3.2和PostgreSQL 12

推荐答案

ActiveRecord::Resultcast_values方法(它在引擎盖下使用deserialize)

query = <~SQL
  SELECT ARRAY_AGG(u.id) AS awesome_data
  FROM u
  GROUP BY condition
SQL
ActiveRecord::Base.connection.exec_query(query).cast_values.flatten
# => [1, 2, 3, 4] # Ruby array of integers

如果要清理SQL,请不要直接使用send次调用的清理方法

这些方法不是私有的,而是public

ActiveRecord::Base.sanitize_sql([query])

您还可以使用Arel来生成经过清理的SQL

u = Arel::Table.new('u')

query =
  u.project(Arel::Nodes::NamedFunction.new('ARRAY_AGG', [u[:id]]).as('awesome_data'))
   .group('condition')
   .to_sql

Ruby-on-rails相关问答推荐

Rails HotWire和View Components:涡轮框架不会取代内容

参数数量错误(给定1个,预期为0个;必需关键字:IO、文件名)-活动存储

在Ruby on rails中,重复访问ActiveRecordModel返回相同的对象:预期行为还是错误?

Heroku、Selenium、Chome和Chromedriver的复杂问题(抱歉,无法简单描述,请阅读详细信息)

如何在 JR gem 中指定每个资源的最大页面大小配置

如何配置我的 Rails 应用程序(使用 Puma)以通过 HTTPS 提供服务?

为什么有时会出现类型错误没有将 StringIO 隐式转换为 String?Ruby /导轨

无法加载此类文件 -- mysql2/mysql2

骨干model.destroy()即使工作正常也会调用错误回调函数?

如何在 Ruby on Rails 中创建一个锚点并重定向到这个特定的锚点

Rails 助手应该假设实例变量存在还是应该将它们作为参数接收?

如何在 Windows 上为 Ruby 安装 sqlite3?

Rails 引擎中的迁移?

使用god 监控独角兽 - 以非零代码开始退出 = 1

如何在 RSpec 中包含 Rails 助手

Rails 控制台中手动更新属性值的验证问题

将 Rails 服务器绑定到 0.0.0.0 能给你带来什么?

您将如何解析 Ruby 中的 url 以获取主域?

测试和规格有什么区别?

如何删除特殊字符?