如何将此 jsonb SQL 查询转换为 Active Record 查询?
How to translate this jsonb SQL query to an Active Record query?
我的 Color
ActiveRecord 模型中存在以下数据:
id
colored_things
1
[{"thing" : "cup", "color": "red"}, {"thing" : "car", "color": "blue"}]
2
[{"thing" : "other", "color": "green"}, {"thing" : "tile", "color": "reddish"}]
3
[{"thing" : "unknown", "color": "red"}]
4
[{"thing" : "basket", "color": "velvet or red or purple"}]
colored_things
列定义为jsonb。
我正在尝试搜索所有 "color"
键以获取 类似于 特定搜索词的值。这个 SQL 查询(参见 SQL Fiddle)是这样做的:
SELECT DISTINCT C.*
FROM colors AS C,
jsonb_array_elements(colored_things) AS colorvalues(colorvalue)
WHERE colorvalue->>'color' ILIKE '%pur%';
现在我很想将此查询转换为适当的 Active Record 查询,但以下内容不起作用:
Color.joins(jsonb_array_elements(colored_things) AS colorvalues(colorvalue))
.where("colorvalue->>'color' ILIKE '%?%'", some_search_term)
.distinct
这给了我错误:
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: invalid reference to FROM-clause entry for table "colors")
有人能给我指出正确的方向吗?
如果您使用 ActiveRecord,情况不会有太大变化,而且如果您将查询保留在 SQL.
中,IMO 仍然更具可读性
为了让它工作,你可以使用 from
,然后传递你当前拥有的 raw FROM
子句:
from("colors AS c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
如果您的表和别名已经可以访问,那么您可以将 WHERE
和 SELECT
子句与其相应的 AR 方法链接起来:
Color
.from("colors AS c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
.where("colorvalue->>'color' ILIKE '%pur%'")
.select("DISTINCT c.*")
注意 where("colorvalue->>'color' ILIKE '%?%'", value)
将不起作用,因为 value
被 ORM 引用,因此您必须构造 "%value%
" 并将其用作绑定值:
where("colorvalue->>'color' ILIKE ?", "%#{value}%")
我的 Color
ActiveRecord 模型中存在以下数据:
id | colored_things |
---|---|
1 | [{"thing" : "cup", "color": "red"}, {"thing" : "car", "color": "blue"}] |
2 | [{"thing" : "other", "color": "green"}, {"thing" : "tile", "color": "reddish"}] |
3 | [{"thing" : "unknown", "color": "red"}] |
4 | [{"thing" : "basket", "color": "velvet or red or purple"}] |
colored_things
列定义为jsonb。
我正在尝试搜索所有 "color"
键以获取 类似于 特定搜索词的值。这个 SQL 查询(参见 SQL Fiddle)是这样做的:
SELECT DISTINCT C.*
FROM colors AS C,
jsonb_array_elements(colored_things) AS colorvalues(colorvalue)
WHERE colorvalue->>'color' ILIKE '%pur%';
现在我很想将此查询转换为适当的 Active Record 查询,但以下内容不起作用:
Color.joins(jsonb_array_elements(colored_things) AS colorvalues(colorvalue))
.where("colorvalue->>'color' ILIKE '%?%'", some_search_term)
.distinct
这给了我错误:
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: invalid reference to FROM-clause entry for table "colors")
有人能给我指出正确的方向吗?
如果您使用 ActiveRecord,情况不会有太大变化,而且如果您将查询保留在 SQL.
中,IMO 仍然更具可读性为了让它工作,你可以使用 from
,然后传递你当前拥有的 raw FROM
子句:
from("colors AS c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
如果您的表和别名已经可以访问,那么您可以将 WHERE
和 SELECT
子句与其相应的 AR 方法链接起来:
Color
.from("colors AS c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
.where("colorvalue->>'color' ILIKE '%pur%'")
.select("DISTINCT c.*")
注意 where("colorvalue->>'color' ILIKE '%?%'", value)
将不起作用,因为 value
被 ORM 引用,因此您必须构造 "%value%
" 并将其用作绑定值:
where("colorvalue->>'color' ILIKE ?", "%#{value}%")