I have two Models in my Rails 6 / PostgreSQL application which have a many to many relation; Car
and Driver
. The goal is to get all records (Cars) which have no association at all (Drivers). At the moment this is done using Ruby (2.6.3) like this:
result = []
Car.all.each do |car|
result << car.id if car.drivers.empty?
end
Is there an ActiveRecord expression which avoids instantiating each record?
-
\$\begingroup\$ Have a look at the ActiveRecord Query Interface. \$\endgroup\$Greg Burghardt– Greg Burghardt2019年09月13日 16:55:49 +00:00Commented Sep 13, 2019 at 16:55
1 Answer 1
To produce the set of records only in cars
, but not in drivers
, you perform a left outer join, then exclude the records you don't want from the right side via a where clause.
In Rails 6 you do this in this way:
Car.left_outer_joins(:drivers).where(car_drivers: { id: nil })
Take a look at this article: A Visual Explanation of SQL Joins. It may help you figure out how to do some queries.
Aside from this, a good way to iterate over an array to select some elements according to a condition is to use the select
method. Using select
your code would be like this:
result = Car.all.select { |car| car.drivers.empty? }
But that is not the way to go here, I'm just showing how to use select
.
Also, if you want only the id
from the cars, you can add pluck(:id)
at the end of the query. This is going to get only the id
field from the database. Or you just use the method ids
but the pluck
method works for any field.