Rails 3 / Ruby: ActiveRecord Find method IN condition Array to Parameters single quote issue
I created a method on a micropost model which takes an array of user_ids. In this method I use the following 'find' method to pull all posts for all of the users within the array.
find(:all, :conditions => ["user_id IN (?)", args.join(',')])
But when ActiveRecord generates the SQL for this query it surrounds the coma delimited list of Ids in single quotes. This causes the query to only pull posts for the first number within the single quotes instead of all the numbers.
SELECT `microposts`.* FROM `microposts` WHERE (user_id IN ('3,4,5')) ORDER BY microposts.created_at DESC
The query should look like this to work correctly but I can't figure out how to get Ruby to convert the Array to a coma delimited list without the quotes, I know it has to be something simple and I am just missing it and can't find anything on Google that fixes this. All the posts I have found use the same .join(',') method to concert the Array.
SELECT `microposts`.* FROM `microposts` WHERE (user_id IN (3,4,5)) ORDER BY microposts.created_at DESC
One more fact which migh assist you in figuring out my issue is the Array of ids which I am passing into开发者_如何学C the method is being built in the following manner. Not sure if this would affect things.
ids = Array.new
ids.push(current_user.id)
ids = ids + current_user.friends.map(&:id)
ids = ids + current_user.reverse_friends.map(&:id)
Thanks in advance to the one who can help me get back to work ;)
Answer updated (twice) to reflect Rails 3+ ActiveRecord syntax
Rails 3+
You can use the following syntax:
Post.where(user_id: [1,2,3])
And thus:
Post.where(user_id: args)
Rails 3 or Rails 4 (Original)
For completeness, the Rails 3 syntax would be:
Post.where("user_id IN (?)", [1,2,3]).to_a
If args is an Array
, then:
Post.where("user_id IN (?)", args).to_a
Or, if args is an array of strings:
Post.where("user_id IN (?)", args.map(&:to_i)).to_a
The to_a
is optional, but will return the results as an array. Hope this helps.
Rails 2
You should be able to simply pass in an array as the parameter, as follows:
find(:all, :conditions => ["user_id IN (?)", [1,2,3] ] )
Thus, if args is an array of ids, you should simply call:
find(:all, :conditions => ["user_id IN (?)", args ] )
In case you have an issues with types, you can do:
find(:all, :conditions => ["user_id IN (?)", args.map { |v| v.to_i } ] )
and this will ensure each item in the array is an Integer.
In rails 3 and 4, you could also simply pass the array as an argument like so:
Post.where(:user_id => [1,2,3])
And that will give you the same result as
Post.where("user_id IN (?)", [1,2,3])
精彩评论