-1

I have three models: A User model, a Post model, and a Comment model. A user can create a post, and then inside a post's show page, there is a list of comments with a form to post a comment. A comment is posted and displayed on the post's show page. I chose to nest comments inside posts, and leave users alone. Here are my routes.rb and each of my models

resources :users, except: [:index]

resources :posts, except: [:index, :edit, :update] do resources :comments, only: [:create, :destroy] end

class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :comments, foreign_key: "author_id"

class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy

class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :author, class_name: "User"

My problem lies with the association between User and Comment (I believe). In my post/show view, I have the following code:

<% if @comments.any? %>
                <% @comments.each do |comment| %>
                    <p><%= comment.author_id %>: <%= comment.content %></p>
                <% end %>
            <% end %>

This code works, for example it prints the following for a comment (assuming the user who created it has id of 15)

15: this is a comment

By this, it is clear to me that it is picking up on who its author is. BUT HERE IS THE ISSUE: When I try to print out the following:

<p><%= comment.author.full_name %>: <%= comment.content %></p>

It gives me this "Action Controller: Exception Caught" error:

"undefined method `username' for nil:NilClass"

Shouldn't the association be able to pick up the author's (user's) full_name property for me? I know I am missing something here, ANY help is greatly appreciated. I am going to also include my posts controller and comments controller right below. My posts controller show action:

def show
    @post = Post.find(params[:id])
    @comment = @post.comments.build
    @comments = @post.comments
end

And here is my comments controller create action followed by my strong params:

def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.build(comments_params)
    if @comment.save
        flash[:good] = "Your comment has been posted!"
        redirect_to @post
    else
        flash[:bad] = "Sorry, your comment failed to post."
        redirect_to @post
    end
end

def comments_params
        params.require(:comment).permit(:content, :author_id)
    end
Parker
  • 493
  • 1
  • 4
  • 14

2 Answers2

1

The error suggests you have an issue with the association.


The quick fix would be to use try:

<%= comment.author.try(:full_name) %>

This is the equivalent of... <%= comment.author.full_name if comment.author %>

--

I'd personally use the following:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :comments, foreign_key: :author_id
end

#app/models/comment.rb
class Comment < ActiveRecord::Base
   belongs_to :author, class_name: "User"
end
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
0

Make sure your comment is indexed with user and post.

User model:

User model: class User < ActiveRecord::Base
  has_many :posts, dependent: :destroy
end

Post model

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments, dependent: :destroy
end

Comment Model

class Comment < ActiveRecord::Base
  belongs_to :post
  belongs_to :author, class_name: "User",  foreign_key: "user_id"
end

In your views:

<% if @comments.any? %>
         <% @comments.each do |comment| %>
              <p><%= comment.author.full_name %>: <%= comment.content %></p>
         <% end %>
 <% end %>
mrvncaragay
  • 1,240
  • 1
  • 8
  • 15