简体   繁体   English

如何将此 jsonb SQL 查询转换为 Active Record 查询?

[英]How to translate this jsonb SQL query to an Active Record query?

The following data is present in my Color ActiveRecord model:以下数据出现在我的Color ActiveRecord model 中:

id ID colored_things有色的东西
1 1 [{"thing": "cup", "color": "red"}, {"thing": "car", "color": "blue"}]
2 2 [{"thing": "other", "color": "green"}, {"thing": "tile", "color": "reddish"}]
3 3 [{"thing": "unknown", "color": "red"}]
4 4 [{"thing": "basket", "color": "velvet or red or purple"}]

The colored_things column is defined as jsonb. coloured_things 列定义为colored_things

I am trying to search on all "color" keys to get values that are like a certain search term.我正在尝试搜索所有"color"键以获取类似于某个搜索词的值。 This SQL query (see SQL Fiddle ) does that:这个 SQL 查询(参见SQL Fiddle )这样做:

SELECT DISTINCT C.*
FROM colors AS C,
jsonb_array_elements(colored_things) AS colorvalues(colorvalue)
WHERE colorvalue->>'color' ILIKE '%pur%';

Now I would love to translate this query to a proper Active Record query, but the below does not work:现在我很想将此查询转换为正确的 Active Record 查询,但以下内容不起作用:

Color.joins(jsonb_array_elements(colored_things) AS colorvalues(colorvalue))
  .where("colorvalue->>'color' ILIKE '%?%'", some_search_term)
  .distinct

This gives me error这给了我错误

ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: invalid reference to FROM-clause entry for table "colors") ActiveRecord::StatementInvalid(PG::UndefinedTable:错误:对表“颜色”的 FROM 子句条目的引用无效)

Can someone point me in the proper direction?有人可以指出我正确的方向吗?

The thing doesn't change that much if you use ActiveRecord, and IMO it remains more readable if you leave your query as it's in SQL.如果您使用 ActiveRecord,事情并没有太大变化,而 IMO 如果您将查询保留在 SQL 中,它仍然更具可读性。

For making it work you can use from , and there pass the raw FROM clause you currently have:为了使其工作,您可以使用from ,并传递您当前拥有的原始FROM子句:

from("colors AS c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")

Having that your tables and aliases are already accessible, so you can chain the WHERE and SELECT clause, with their corresponding AR methods:既然您的表和别名已经可以访问,那么您可以将WHERESELECT子句及其相应的 AR 方法链接起来:

Color
  .from("colors AS c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
  .where("colorvalue->>'color' ILIKE '%pur%'")
  .select("DISTINCT c.*")

Notice where("colorvalue->>'color' ILIKE '%?%'", value) will not work because value is quoted by the ORM, so instead you have to construct the " %value% " and use it as the bound value:请注意where("colorvalue->>'color' ILIKE '%?%'", value)将不起作用,因为 ORM 引用了value ,因此您必须构造“ %value% ”并将其用作边界价值:

where("colorvalue->>'color' ILIKE ?", "%#{value}%")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM