I have a problem where rails is adding unnecessary (I think) clauses to my belongs_to association – restricting on type even though my association is using a foreign key.
The STI setup looks like this:
class Foo < ActiveRecord::Base
belongs_to :apple
end
class Apple < Fruit
has_many :foos
end
So Foo has an apple_id column which links to the primary key column ID in fruits, and Apple is STI under Fruit. I’m happy with all of this.
Now:
> Foo.joins(:apple).to_sql
SELECT "foos".* FROM "foos" INNER JOIN "fruits" ON "fruits"."id" =
"foos"."apple_id" AND "fruits"."type" IN ('Apple')
Why is rails adding AND "fruits"."type" IN ('Apple')? It’s a belongs_to using a primary key of the fruits table, so the type part seems redundant. Can I stop rails from adding that part to the lookups and just get this:
SELECT "foos".* FROM "foos" INNER JOIN "fruits" ON "fruits"."id" =
"foos"."apple_id"
I know I could do belongs_to :apple, :class_name => "Fruit" in Foo, but I want the objects to auto-become Apples when they’re returned.
In case someone questions my motives… I want to do this because the type clause is messing up the query plan postgres chooses when I’m doing a query through fruits to other tables (yes, I have an index on type and even tried a multi-column one on [type,id]). That’s a little complicated / irrelevant to describe fully here.
Basically AM is adding the (‘Apple’) part because in order to respect the inheritance chain.
For example if you’d have
You’ll get.
If for whatever reason you end up having on your fruits tabel a fruit with a referenced pk but with a different type you could end up instantiating a different kind of object without knowing it and after that things can go wrong without getting an exception.