Bernardo Loureiro
Bernardo Loureiro

Reputation: 453

Rails: polymorphic associations, find commented on

I've implemented polymorphic comments on my Rails app using this tutorial.

So I have:

class Place < ApplicationRecord
  has_many :comments, as: :commentable
end

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
end

Now I want to index all comments and join them with the places they comment on, but I have no idea on how to achieve this.

In my comments_controller.rb I have:

class CommentsController < ApplicationController
  def index
    @comments = Comment.all
  end
end

And in my comments index.html.erb I can access:

<%= comment.commentable_type %>
<%= comment.commentable_id %>

But how do I access the actual attributes of what the comments are on, example: <%= comment.place.name %>?

I believe it is related to this answer but I don't know how: rails joins polymorphic association

Upvotes: 0

Views: 269

Answers (2)

Bernardo Loureiro
Bernardo Loureiro

Reputation: 453

mccalljt answer's above is much better

Believe I've got it:

Added to comment.rb:

belongs_to :place, foreign_key: 'commentable_id'

Added to comments_controller.rb:

@comments = Comment.where(commentable_type: "Place").joins(:place)

Though this is not reusable when there are more associations, but I could change it to:

@place_comments = Comment.where(commentable_type: "Place").joins(:place)
@other_comments = Comment.where(commentable_type: "Other").joins(:other)

Upvotes: 0

mccalljt
mccalljt

Reputation: 796

You can refer to the commentable object with just

comment.commentable

The only thing to watch out for here is that it assumes that all your commentables have the method you call on them, such as name.

comment.commentable.name

You will want to preload these in your controller to avoid an N+1 as well.

class CommentsController < ApplicationController
  def index
    @comments = Comment.includes(:commentable).all
  end
end

Upvotes: 1

Related Questions