For example I have 2 tables: topics and comments.
topic has_many comments. comment belongs_to topic.
Comments table have column sender_id where I save user’s id, who create this comment.
Task: Select ids of topics, which is not commented by this user (I know user_id).
(I want to do it with one query).
Earlier I do it so. ( two queries ) ( My database – PostgreSQL)
incorrect_topics = Comment.select(:topic_id).where(:sender_id => user_id).map { |elem| elem.topic_id }
ids = select(:id).where(["id NOT IN (?)", incorrect_topics]).map { |elem| elem.id }
It works fine, but I suppose that if app become bigger it will be serious problem.
Thanks.
If all you need are the IDs then you could bypass all the ActiveRecord stuff and do it by hand:
If you’re certain the
user_idis already an integer then you don’t need the.to_i. You could also use#{connection.quote(user_id)}. You could also use the same SQL withselect_valuesif you wanted to avoid unwrapping he rows by hand with amap.If you wanted the Topic instances then
find_by_sqlwould be an option:Some things are clearer when you use straight SQL than when you try to wrap it up in ActiveRecord stuff.