0

Let's say there is a model called User. That has the attribute :hobbies.

user = User.first
user.hobbies
=> ["Bowling", "Cooking", "Knitting"]

If I wanted to use a .where searching for the :hobbies attribute, how would I do that? I'm using postgresql, and

:hobbies, :text, array:true

User.where(hobbies: "Anything I put here, string array, hash") throws the error

ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR:  malformed array literal:

2 Answers 2

1

Remember that you can use any SQL you want by passing a string to where, e.g.:

User.where("hobbies @> ARRAY['Bowling', 'Cooking', 'Knitting']")

or

User.where("hobbies && ARRAY['Bowling', 'Cooking', 'Knitting']")

Postgres has good documentation of the array operators available.

Sign up to request clarification or add additional context in comments.

4 Comments

Would any of these translate into WHERE hobbies IN('Bowling', 'Cooking', 'Knitting')? 'Cos that would be the optimal query.
COUNT does not tell you the length of the array, but it tells you how many rows are getting rollup up in an aggregate query. That's why it's always giving you 1: no matter how long the array, there is still just one row. You probably want array_length(hobbies, 1). But I'm not actually sure what you're trying to do, so I could be on the wrong track.
The reason you can't use IN here is because hobbies is not a string, but an array of strings. So you should use the array operators instead. @> means hobbies has all of Bowling, Cooking, and Knitting. && means it has at least one of them.
@PaulAJungwirth: Thank you for point out the contains operator specifically. My query that I was using to understand the operators was poor, and you pointing out that operator gave me my "Aha!" moment that my query was all contained by the attribute. I got used to working with joins.
0

You may try contains or overlap from postgres_ext gem. Just install the gem and then query:

query = ["Bowling", "Cooking", "Knitting"]

#With Overlap operator:
User.where.overlap(hobbies: query)

#or with Contains Operator
User.where.contains(hobbies: query)

2 Comments

undefined method `overlap' for #<ActiveRecord::QueryMethods::WhereChain:0x007fadef6c0b98>. Same goes for contains :l
Ah, my bad! You'd need postgres_ext gem for this to work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.