ActiveRecord Rails 4、如何查看数组属性是否包含数组中的任何值

ActiveRecord Rails 4, how to look if array attribute contains any of values in array

假设我有一个 Book 模型,它的 categories 属性是一个数组。 我想创建一个范围,在其中我可以从我要传入的另一个数组中获取至少包含一个项目的所有书籍。

在广泛搜索并尝试许多不同的查询之后,我找到的最接近的是:

Book.where("'Mystery' = ANY(categories)")

如何将 'Mystery' 替换为类似 ['Categ1', 'Categ2', etc...] 的内容,以便我可以检索至少包含数组中一个值的任何书籍?

你需要知道三件事:

  1. PostgreSQL 的数组重叠运算符:&&。如果两个数组有任何共同元素,则 array1 && array2 为真。
  2. PostgreSQL 的 array constructor syntax,即 array[v1, v2, v3].
  3. 如果占位符的值是 Ruby 数组,那么 ActiveRecord 将用逗号分隔的列表替换 ? 占位符,因此 where('c = any(array[?])', [1,2,3]) 看起来像 c = any(array[1,2,3])它进入数据库。

如果你把所有这些放在一起,你会得到这样的东西:

categories = %w[Categ1 Categ2 Categ3]
Book.where('categories && array[?]', categories)

你的范围是这样的:

scope :with_any_categories, ->(cats) { where('categories && array[?]', cats) }

或者也许:

scope :with_any_categories, ->(*cats) { where('categories && array[?]', cats.flatten) }

取决于您希望如何使用示波器。