I currently have this code:
class Group < ActiveRecord::Base
has_many :roles
#can't find better name for this method
def self.without_role_ids
find_by_sql('select id from groups where id not in
(select distinct group_id from roles)').map { |g| g.id }
end
end
class Role < ActiveRecord::Base
belongs_to :group
end
without_role_ids method outputs ids of groups that doesn’t have any roles.
What I’m trying to do is to rewrite this method:
def self.without_role_ids
where("id NOT IN (?)", Role.pluck(:group_id))
end
And it produces two queries.
It is possible to run
where(id: Role.select(:group_id))
and it will produce exactly one SQL query, but with IN instead of NOT IN which I need.
Is it possible to do NOT IN with one query without using find_by_sql?
I found a solution, it is easy to perform such queries with Squeel:
https://github.com/ernie/squeel
Now methods code is:
and it produces this query:
There is the Railscast about Squeel: http://railscasts.com/episodes/354-squeel