1

So I am attempting to do a SQL query where I need to provide a lot of user id's.

Currently what I am trying to do is this:

following_ids = $redis.smembers(self.redis_key(:following))
Medium.includes([{comments: :user}, :likes, :user]).where("user_id IN (#{ following_ids.each { |id| id } }) OR user_id = :user_id", user_id: id)

Now the following_ids is in this form: ["1", "2", "3"], containing user id's

But the loop I try to do seems to still put the whole array into the SQL statement. I can see this from my server log:

Medium Load (0.3ms)  SELECT "media".* FROM "media" WHERE (user_id IN (["2", "3"]) OR user_id = 1)
PG::SyntaxError: ERROR:  syntax error at or near "["
LINE 1: SELECT "media".* FROM "media" WHERE (user_id IN (["2", "3"])...

What am I doing wrong here?

2
  • You want it to be in the form ("1", "2", "3")? Commented Dec 30, 2014 at 22:51
  • Yes. It should look something like this: IN (id1, id2, id3... idx), so without the [] brackets Commented Dec 30, 2014 at 22:52

2 Answers 2

2

You don't need to complicate things that much. You could simply do

user_ids = $redis.smembers(self.redis_key(:following)) << id
Medium.includes([{comments: :user}, :likes, :user]).where(user_id: user_ids)
Sign up to request clarification or add additional context in comments.

1 Comment

That is an even better approach. Thank you!
1

Try changing the interpolated code to:

following_ids.to_s.tr("[]", "")

So in total:

Medium.includes([{comments: :user}, :likes, :user]).where("user_id IN ( #{following_ids.to_s.tr("[]", "") }) OR user_id = :user_id", user_id: id)

UPDATE: See Kaspar's comment below for the preferred 'active record way' to do this.

2 Comments

Seems to work well, meanwhile found out that this is possible too actually: Medium.includes([{comments: :user}, :likes, :user]).where("user_id IN (?) OR user_id = ?", following_ids, id). Will see which one I shall use. Thank you for the help!
@Kaspar Oh yeah totally. That is actually the preferred way to do it! I should have thought of that. Will edit my answer to refer to your comment.

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.