Reputation: 4861
Is it possible to eager load polymorphic nested associations? How can I include
doctor_profile
's for Recommendation
's and patient_profile
's for Post
's?
I'm able to call Activity.includes(:trackable).last(10)
but not sure how to include the associated models past there. I've tried belongs_to :recommendation, -> { includes :patient_profile, :doctor_profile}
with no luck
class Activity
belongs_to :trackable, polymorphic: true
end
class Recommendation
has_many :activities, as: :trackable
belongs_to :doctor_profile
end
class Post
has_many :activities, as: :trackable
belongs_to :patient_profile
end
Upvotes: 1
Views: 886
Reputation: 429
In order to get the above answer to work, specifying inverse_of
for the belongs_to
and adding for the has_many
associations got everything to work. For example:
class Activity
belongs_to :trackable, polymorphic: true
# below is additional info
belongs_to :recommendation, foreign_type: 'Recommendation', foreign_key: 'trackable_id', inverse_of: :activities
belongs_to :post, foreign_type: 'Post', foreign_key: 'trackable_id', inverse_of: :activities
end
On the Post
model:
has_many :activities, inverse_of: :post
On the Recommendation
model:
has_many :activities, inverse_of: :recommendation
Upvotes: 0
Reputation: 1
The above answer works, but the use of foreign_type
isn't actually supposed to do what the commenter intended.
https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
foreign_type
is used to specify the name for the column which determines the class type for the relation.
I think the intended result here is to instead use class_name
to specify which table the relation is referring to. If the relation has the same name as the table, then class_name
can actually be inferred (which is why the provided answer works in the first place)
Upvotes: 0
Reputation: 6253
with respect referenced this SO answer and comments for your problem you can managed with foreign_type field from polymorphic table to reference which model that use it
class Activity
belongs_to :trackable, polymorphic: true
# below is additional info
belongs_to :recommendation, foreign_type: 'Recommendation', foreign_key: 'trackable_id'
belongs_to :post, foreign_type: 'Post', foreign_key: 'trackable_id'
end
and you can call it
Activity.includes(recommendation: :doctor_profile).last(10)
Activity.includes(post: :patient_profile).last(10)
Activity.includes(recommendation: :doctor_profile) means
Upvotes: 2