在作为数组的列上使用WHERE无法正常工作

时间:2019-02-18 13:22:07

标签: ruby-on-rails arrays where

我有一个表,其中的列是数组。表中的记录在["something","another thing"]列中具有数组values。但是在执行where查询时由于某些原因它们没有显示。所以我不确定我在做什么错。

# schema
t.text "values", default: "--- []\n"

# model
serialize :values, Array

# rails console
> Table.where(values: ["something","another thing"])
SELECT "tables".* FROM "tables" WHERE "tables"."values" IN ('something', 'another thing')
 => #<ActiveRecord::Relation []> 

所以我想要创建的理想的SQL输出可能就像...

SELECT "tables".* FROM "tables" WHERE "tables"."values" = ?  [["values", ["something", "another thing"]]]

代替数组似乎正在创建的IN查询

2 个答案:

答案 0 :(得分:0)

由于该列已序列化为数组,所以所需的值将存储为

"---\n- something\n- another thing\n"

在数据库中是一个字符串。

要通过SQL查找此类记录,很遗憾,您将不得不依靠LIKE

Table.where(["values LIKE ?", '%something\n- another thing%'])

如果它们之间可以有其他值或顺序可以更改,则还必须考虑到这一点。还请在我的网站中承担此类查询对性能的影响。

搜索序列化列只是不应该做的事情。

答案 1 :(得分:0)

我可以同意搜索序列化数据可能效率不高。 但是这是我遇到的解决方案。

# model
scope :matching_values, -> (values) { where(matching_value_query(values, 'AND')) }
scope :subset_of_values, -> (values) { where(matching_value_query(values, 'OR')) }

def self.matching_value_query(values, condition_separator = 'OR')
  values.map { |value| "(values LIKE '%#{value}%')" }.join(" #{condition_separator} ")
end

# rails console
Table.matching_values(["something","another"])
 SELECT "tables".* FROM "tables" WHERE ((values LIKE '%something%') AND (values LIKE '%another%'))
=> #<ActiveRecord::Relation [ full of stuff ]