I'm going to assume your join table is called cars_locations
. If you wanted to do this just in sql, you could join this table to itself
... cars_locations cl1 join cars_locations cl2 on e1.car_id = e2.car_id ...
... which would make a pseudo-table for the duration of the query with this structure:
cl1.id | cl1.car_id | cl1.location_id | cl2.id | cl2.car_id | cl2.location_id
then query this for the required location_id - this will give you entries that have the same car at both locations - let's say the ids of the pickup and return locations are 123 and 456:
select distinct(cl1.car_id) from cars_locations cl1 join cars_locations cl2 on cl1.car_id = cl2.car_id where (c11.location_id = 123 and cl2.location_id = 456) or (cl1.location_id = 123 and cl2.location_id = 456);
Now we know the sql, you can wrap it into a method of the Car class
#in the Car class
def self.cars_at_both_locations(location1, location2)
self.find_by_sql("select * from cars where id in (select distinct(cl1.car_id) from cars_locations cl1 join cars_locations cl2 on cl1.car_id = cl2.car_id where (c11.location_id = #{location1.id} and cl2.location_id = #{location2.id}) or (cl1.location_id = #{location2.id} and cl2.location_id = #{location1.id}))")
end
This isn't the most efficient method, as joins on big tables start to get very slow. A quicker method would be
def self.cars_at_both_locations(location1, location2)
self.find(location1.car_ids & location2.car_ids)
end
in this case we use &
which is the "set intersection" operator (not to be confused with &&
): ie it will return only values that are in both the arrays on either side of it.