【问题标题】:ActiveRecord Query to find JSON Value Array for a given KeyActiveRecord 查询以查找给定键的 JSON 值数组
【发布时间】:2015-07-26 17:09:45
【问题描述】:

在 Rails 4 中,我有一个带有 JSON 类型列的表。我有一个像这样效果很好的方法

def self.that_match_property(key: "default", value: "default")
  where("properties ->> ? = ?", key, value)
end

所以对于Model.first.properties,我得到{"name": "Bill", "user_id": "1"} 我可以做到这一点。

Model.that_match_property(key: "name", value: "Bill") 

我在我的 json properties 列中获得了与键/值对匹配的记录。

但是...假设我希望该值是一个 id 数组。所以我有...

user1.properties = {"name": "Bill", "user_id": "1"}
user2.properties = {"name": "Ted", "user_id": "2"}
user3.properties = {"name": "Rufus", "user_id": "3"}

现在我也有bill_and_ted_ids = ["1", "2"]

我希望能够做到这一点:

Model.that_match_property(key: "user_id", value: bill_and_ted_ids)

但这不起作用。通常我可以将一组 ID 传递给活动记录查询,然后它会转换为正确的 sql。

在 Rails 中使用 JSON 数据类型执行上述操作的正确方法是什么?

【问题讨论】:

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


    【解决方案1】:

    也许这样的事情会有所帮助:

    def build_where_query_string_from_hash(hash)
      hash.collect do |k,v|
        if v.is_a?(Array)
          string = v.collect{|e| "(properties ->> '#{k}'='#{e}')"}.join(" OR ")
          "(#{string})"
        else
          "(properties ->> #'{k}'='#{v}')"
        end
      end.join(" AND ")
    end
    

    那么你就可以通过了:build_where_query_string_from_hash(user_id: [1,2], name: ["Bill", "Ted"])

    返回:

    ((properties ->> 'user_id'='1') OR (properties ->> 'user_id'='2')) AND ((properties ->> 'name'='Bill') OR (properties ->> 'name'='Ted'))`
    

    【讨论】:

    • 谢谢...我试图避免使用 2 个 ruby​​ 循环。我已经让它工作了,我可以循环遍历 ID 并使用每个 ID 调用方法。我希望改进并使用 AR 惰性评估来提高效率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多