You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rails 5.2.4的Postgres Arel查询中提取JSON元素?

解决方法

1. 问题根源

你的Parameter模型里name字段被ActiveRecord映射为JSON/Hash类型,但查询时用as name把字符串结果覆盖了这个字段。ActiveRecord会尝试把返回的字符串解析成JSON,而单个字符串(比如"New")不是合法的JSON对象,解析失败后就返回null。

2. 方案一:换个查询别名

别用name当别名,换个比如english_name,让ActiveRecord直接返回字符串:

原生SQL写法

options = Parameter.select(
  :id, :code, :sort_code, :property,
  "(name ->> 'en') as english_name"
).where(parameters_list_id: 3)

Arel写法

name_col = Parameter.arel_table[:name]
english_name = name_col.send(:'->>', 'en').as('english_name')

options = Parameter.select(
  :id, :code, :sort_code, :property,
  english_name
).where(parameters_list_id: 3)

之后用record.english_name就能拿到对应的英文名称。

3. 方案二:模型里加方法(推荐)

在Parameter模型里写个实例方法,直接从JSON字段取对应语言的值,不用在查询里折腾:

class Parameter < ApplicationRecord
  def name_in(locale = I18n.locale)
    name[locale.to_s] if name.present?
  end
end

查询时直接拿全字段,之后调用方法:

options = Parameter.where(parameters_list_id: 3)
options.each do |param|
  puts param.name_in('en') # 输出英文名称
end

这种方式符合Rails约定,后续改语言也方便,直接传不同locale就行。

4. 方案三:用Rails内置JSON查询API(Rails 5+)

Rails 5及以上支持直接用ActiveRecord的JSON方法,不用写原生SQL:

options = Parameter.select(
  :id, :code, :sort_code, :property,
  Parameter.arel_table[:name].get_text('en').as('english_name')
).where(parameters_list_id: 3)

get_text对应PostgreSQL的->>运算符,返回文本类型,别名避免冲突。


内容的提问来源于stack exchange,提问作者user1185081

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 23:50:28