This is a challenging case for ActiveRecord. It needs to infer that columns in the self-join needed to find districts
are STI instances. Apparently it's not smart enough to get this right. Since the only table is places
, it's not much of a surprise that it generates this query:
SELECT "places".* FROM "places"
INNER JOIN "places" "cities_districts_join"
ON "places"."parent_id" = "cities_districts_join"."id"
WHERE "places"."type" IN ('City') <<<<< ERROR HERE
AND "places"."type" IN ('District')
AND "cities_districts_join"."parent_id" = ?
As you can see the type check must fail since one string can't be both City
and District
. All would work if the first clause in the WHERE
were instead
WHERE "cities_districts_join"."type" IN ('City')
I tried several options on the relations (thought :class_name
might do it), but no joy.
You can work around this limitation with SQL. Delete the has_many ... through
in the Country
class and replace with
def districts
District.find_by_sql(['SELECT * from places AS city
INNER JOIN places AS district
ON district.parent_id = city.id
WHERE city.parent_id = ?', id])
end
Or maybe someone else will see a more elegant way. If not, you might consider posting this as an issue in Rails development. It's an interesting case.