-
Couldn't load subscription status.
- Fork 211
Join with where block and default is broken. #361
Description
Squeel appears to be broken when defining an association with a where clause of type String, and a default_scope on one of the models.
I'm using rails 4.1.9, though I've seen it on other versions > 4 as well. Using squeel 1.2.3 and postgres.
Models
class Vehicle < ActiveRecord::Base
# Specify a simple string based where clause on the association
has_many :vehicle_assignments, -> { where("vehicles.id = 1") }
end
class VehicleAssignment < ActiveRecord::Base
belongs_to :vehicle
# Add a simple default scope
default_scope lambda {
where(id: 1)
}
end
Code
Vehicle.joins(:vehicle_assignments)
Result
PG::SyntaxError: ERROR: syntax error at or near "="
LINE 1: ..."."id" AND "vehicle_assignments"."id" = 1, (vehicles.id = 1)
SQL
SELECT "vehicles".* FROM "vehicles" INNER JOIN "vehicle_assignments" ON
"vehicle_assignments"."vehicle_id" = "vehicles"."id" AND "vehicle_assignments"."id" = 1, (vehicles.id = 1)
As you can see, the last conditional is not being added to the SQL correctly. We expect AND (vehicles.id = 1) but get , (vehicles.id = 1). My assumption is that this occurs because vehicles.id = 1 is being added as a simple simple string. If we change the syntax to "vehicles.id" => 1 then everything works as expected.
This only occurs when there is both a string based where scope block in the association definition, and when the association's model has a default_scope. The error occurs even when not using squeel syntax anywhere in the app.
I've traced the problem to the collapse_wheres method, specifically in the final code block where String based where clauses are explicitly handled. String based where clauses are added to arel.where but they are never ANDed with the other groups. I'll add a pull request with what I think is a correct solution, though I will mention that I am not deeply versed in arel.
Any input would be greatly appreciated.