user2954587
user2954587

Reputation: 4861

Rails 5.2 eager load polymorphic nested

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

Answers (3)

Sarah Marie
Sarah Marie

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

darth challa
darth challa

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

widjajayd
widjajayd

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

  • Activity will join recommendation with foreign_type and trackable_id
  • and then from recommendation will join doctor_profile with doctor_profile_id

Upvotes: 2

Related Questions