Reputation: 171
Say I have a Book model that has a categories attribute which is an array. I want to create a scope in which I can grab all Books that contain at least one item from another array I want to pass in.
After googling extensively and trying out many different queries, the closest I've found is this:
Book.where("'Mystery' = ANY(categories)")
How can I substitute 'Mystery' to be something like ['Categ1', 'Categ2', etc...]
so that I can retrieve any Book that contains AT LEAST ONE of the values in the array?
Upvotes: 3
Views: 1584
Reputation: 434975
You need to know three things:
&&
. array1 && array2
is true if the two arrays have any elements in common.array[v1, v2, v3]
.?
placeholder with a comma-delimited list so where('c = any(array[?])', [1,2,3])
will look like c = any(array[1,2,3])
when it gets to the database.If you put all those together, you get things like:
categories = %w[Categ1 Categ2 Categ3]
Book.where('categories && array[?]', categories)
and your scope would be like this:
scope :with_any_categories, ->(cats) { where('categories && array[?]', cats) }
or perhaps:
scope :with_any_categories, ->(*cats) { where('categories && array[?]', cats.flatten) }
depending on how you want to use the scope.
Upvotes: 5