ruby Rails 6:强类型原始SQL查询返回数组类型

wbrvyc0a  于 2023-05-28  发布在  Ruby
关注(0)|答案(1)|浏览(94)

由于一些与问题实际上无关的原因,我不得不手动构造一个相当复杂的查询,而不是使用ActiveRecord。这个查询当前返回一个PostgreSQL数组数据类型,我想看看是否可以将它Map到比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

0aydgbwb

0aydgbwb1#

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-直接调用sanitize方法
这些方法不是私有的,而是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

相关问题