-
Notifications
You must be signed in to change notification settings - 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.