I have the following STI models, they have a polymorphic association, whose query is being wrongly constructed
class Product < ApplicationRecord
has_many :images, as: :imageable
end
class OneProduct < Product
end
class Image < ApplicationRecord
belongs_to :imageable
end
In a rails console, when I do
> OneProduct.last.icon_images
The query being fired is
SELECT * FROM images WHERE imageable_id = id AND imageable_type = 'Product'
I was expecting:
SELECT * from images WHERE imageable_id = id AND imageable_type = 'OneProduct'
Am I expecting something wrong?
Side Info: database is postgres.
From the Rails docs:
Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order for the associations to work as expected, ensure that you store the base model for the STI models in the type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts and member posts that use the posts table for STI. In this case, there must be a type column in the posts table.
Note: The
attachable_type= method
is being called when assigning an attachable. Theclass_name
of the attachable is passed as aString
.class Asset < ActiveRecord::Base belongs_to :attachable, polymorphic: true def attachable_type=(class_name) super(class_name.constantize.base_class.to_s) end end class Post < ActiveRecord::Base # because we store "Post" in attachable_type now dependent: :destroy will work has_many :assets,as: :attachable, dependent: :destroy end class GuestPost < Post end class MemberPost < Post end
So it says that instead of storing the imageable_type = OneProduct
you need to store it as Product
only and you can add a type
column in the Product
table. But that depends completely on what you need from the OneProduct
model, if a default_scope
on that model will make it work for you without adding the type
column then don't add it on the Product
table and if that doesn't work then you can add the column and then add the default_scope
to fetch products.type = OneProduct
when querying on OneProduct
model.