You definitely shouldn't be using the locations.id
twice in the where clause, as that is physically impossible. The resulting query from that will essentially try and find the location where it's id is both the handover location, AND the return location. So in essence, what you're asking for is something like
where 1 == 1 AND 1 == 2
Which needless to say, will always return nothing.
In theory if you just change the AND
for an OR
you'll get what you're after. This way, you'll be asking the database for any location that has an ID or either start_location
OR handover_location
UPDATE
Re-read the question. It's a little tricker than I'd thought initially, so you'll probably need to do some processing on the results. As I've said, using the AND query the way you are is asking the database for something impossible, but using the OR as I originally said, will result in cars that have EITHER or the locations, not both. This could be done in raw SQL, but using Rails this is both awkward, and frowned upon, so here's another solution.
Query the data using the OR selector I originally proposed as this will reduce the data set considerably. Then manually go through it, and reject anything that doesn't have both locations:
locations = [params[:cars][:handover_location], params[:cars][:return_location]]
@cars = Car.joins(:locations).where("locations.id IN [?]")
@cars = @cars.reject { |c| !(locations - c.location_ids).empty? }
So what this does, is query all cars that have either of the requested locations. Then it loops through those cars, and rejects any whose list of location id's does not contain both of the supplied IDS. Now the remaining cars are available at both locations :)