【问题标题】:How to translate this jsonb SQL query to an Active Record query?如何将此 jsonb SQL 查询转换为 Active Record 查询?
【发布时间】:2021-07-05 09:32:01
【问题描述】:

以下数据存在于我的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: 错误:对表“颜色”的 FROM 子句条目的引用无效)

有人能指出正确的方向吗?

【问题讨论】:

    标签: sql ruby-on-rails postgresql activerecord ruby-on-rails-6


    【解决方案1】:

    如果您使用 ActiveRecord,事情不会有太大变化,而 IMO 如果您将查询保留在 SQL 中,它仍然更具可读性。

    为了让它工作,你可以使用from,并传递你当前拥有的raw FROM 子句:

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

    如果您的表和别名已经可以访问,那么您可以链接 WHERESELECT 子句,以及它们对应的 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}%")
    

    【讨论】:

    • 当然,from 是缺失的拼图!非常感谢,很好的回答:-)(在 ActiveRecord 中尝试这样做的主要原因是为了防止在清理用户输入时出现一些麻烦。我同意你的观点,纯 SQL 通常更具可读性。)
    • from 涵盖了很多这样的案例,但遗憾的是它缺乏文档。无耻插件,我写了gem,你可以在这些情况下使用。
    猜你喜欢
    • 2014-03-05
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多