我在模型上有一个jsonb列,其中包含(除其他事项外)分数数组。我想找到所有分数数组为空的记录。数据如下:
Model.new(results: {scores: [], other: [], info: {things: 'stuff'}})
不幸的是,尝试查询[]
会转换为搜索NULL
。
Model.where("results -> 'scores' = ?", []).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = NULL)"
我该怎么做?
答案 0 :(得分:1)
ActiveRecord对PostgreSQL的更高级类型(范围,JSON等)的知识和与之的集成是不完整的,因为AR无法理解"results -> 'scores' = ?"
SQL字符串,AR仅看到了(大概)包含SQL的字符串和一个占位符。因此,AR不能理解[]
在替换占位符时应转换为JSON,它只是对数组执行它总是做的事情:空数组变成NULL
,非空数组变成逗号分隔列表(用于in (?)
构造);例如:
Model.where("results -> 'scores' = ?", []).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = NULL)"
Model.where("results -> 'scores' = ?", [6,11,23]).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = 6,11,23)"
您可以通过帮助AR进行#to_json
调用,然后依靠PostgreSQL的自动类型转换来解决此问题:
Model.where("results -> 'scores' = ?", [].to_json).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = '[]')"
Model.where("results -> 'scores' = ?", [6,11,23].to_json).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = '[6,11,23]')"