Rails 4: has_many association: through association with polymorphic association

In my Rails 4 application, I have the following models:

User has_many :administrations has_many :calendars, through: :administrations has_many :comments has_many :calendar_comments, through: :calendars, :source => :comments Calendar has_many :administrations has_many :users, through: :administrations has_many :posts has_many :comments, through: posts has_many :ads Administration belongs_to :user belongs_to :calendar Post belongs_to :calendar has_many :comments, as: :commentable Ad belongs_to :calendar has_many :comments, as: :commentable Comment belongs_to :commentable, polymorphic: true belongs_to :user 

I need to access comments , which belong_to a ad from calendar ad belongs_to .

This is what I am trying to do in my Calendars#Index action:

 @posts_comments = @user.calendar_comments.where(commentable_type: "Post").order("created_at DESC").limit(5) @ads_comments = @user.calendar_comments.where(commentable_type: "Ad").order("created_at DESC").limit(5) 

My first assumption was to add has_many :comments, through: ads to the calendar model:

 Calendar has_many :administrations has_many :users, through: :administrations has_many :posts has_many :comments, through: posts has_many : ads has_many :comments, through: ads 

But this undoes the effect of has_many :comments, through: posts , and then I can no longer access the comments , which belong_to a post from the calendar post belongs_to .

Is there a way to make BOTH has_many :comments, through: posts and has_many :comments, through: ads work?

-----

UPDATE : according to this article and what is stack overflow question , the answer may be to use source: and source_type:

I don’t know how to use them.

-----

UPDATE 2 : will it make sense to use the following code?

 class Calendar < ActiveRecord::Base has_many :administrations, dependent: :destroy has_many :users, through: :administrations has_many :posts, dependent: :destroy has_many :commented_posts, through: :comments, source: :commentable, source_type: 'Post' has_many :ads, dependent: :destroy has_many :commented_ads, through: :comments, source: :commentable, source_type: 'Ad' 

-----

UPDATE 3 : when you try to execute the above code, the following error message appears:

 Could not find the source association(s) :comments in model Calendar. Try 'has_many :calendar_comments, :through => :calendars, :source => <name>'. Is it one of administrations, users, posts, commented_posts, ads, commented_ads, invites, or pokes? 

I tried the following:

 class Calendar < ActiveRecord::Base has_many :administrations, dependent: :destroy has_many :users, through: :administrations has_many :posts, dependent: :destroy has_many :calendar_comments, :through => :calendars, :source => :post has_many :ads, dependent: :destroy has_many :calendar_comments, :through => :calendars, :source => :ad 

-----

UPDATE 4 : A new failed attempt with the following code:

 class Calendar < ActiveRecord::Base has_many :administrations, dependent: :destroy has_many :users, through: :administrations has_many :posts, dependent: :destroy has_many :calendar_comments, :through => :commentable, :source => :post has_many :ads, dependent: :destroy has_many :calendar_comments, :through => :commentable, :source => :ad 

Still not working, same error message as above.

-----

UPDATE 5 : based on MrYoshiji's answer, I now have

 class Calendar < ActiveRecord::Base has_many :administrations, dependent: :destroy has_many :users, through: :administrations has_many :posts, dependent: :destroy has_many :posts_comments, through: :posts, source_type: 'Post' has_many :ads, dependent: :destroy has_many :ads_comments, through: :ads, source_type: 'Ad' 

Now has_many :calendar_comments, through: :calendars, :source => :comments in the User model no longer works.

I tried:

 has_many :comments has_many :calendar_post_comments, through: :calendars, :source => :post_comments has_many :calendar_ad_comments, through: :calendars, :source => :ad_comments 

Still not working.

-----

UPDATE 6 . I am still sticking to this problem since I cannot find a way to get the following code:

 @posts_comments = @user.calendar_comments.where(commentable_type: "Post").order("created_at DESC").limit(5) @ads_comments = @user.calendar_comments.where(commentable_type: "Ad").order("created_at DESC").limit(5) 

I tried a lot of different things, and the best I could come up with was:

 class Calendar < ActiveRecord::Base has_many :administrations, dependent: :destroy has_many :users, through: :administrations has_many :posts, dependent: :destroy has_many :post_comments, through: :posts, source_type: 'Post' has_many :ads, dependent: :destroy has_many :ad_comments, through: :ads, source_type: 'Ad' end class User < ActiveRecord::Base has_many :administrations, dependent: :destroy has_many :calendars, through: :administrations has_many :comments has_many :calendar_post_comments, through: :calendars, :source => :post_comments has_many :calendar_ad_comments, through: :calendars, :source => :ad_comments end 

Then I update my calendar controller as follows:

 def index @user = current_user @calendars = @user.calendars.all @posts_comments = @user.calendar_post_comments .order("created_at DESC") .limit(5) @ads_comments = @user.calendar_ad.comments .order("created_at DESC") .limit(5) end 

But this returns the following error:

 NoMethodError at /calendars undefined method `chain' for nil:NilClass @posts_comments = @user.calendar_post_comments.order("created_at DESC").limit(5) 

What is wrong here?

+7
ruby-on-rails activerecord ruby-on-rails-4 polymorphic-associations has-many-through
source share
1 answer

You should try the following:

 class Calendar < ActiveRecord::Base # [ ... ] has_many :posts has_many :posts_comments, through: posts, source_type: 'Post' has_many :ads has_many :ads_comments, through: ads, source_type: 'Ad' 

Given that the Ad and Post models have the following:

 has_many :comments, as: :commentable 
+3
source share

All Articles