Annette
Annette

Reputation: 317

Show username when posting comments

I would like to be able to display the username of the person who commented on a post. I am having some difficulty displaying it. As the code stands right now I am getting an undefined method `user' for nil:NilClass on the view for line: <%= @comment.user.name %>. Thank you in advance again.

Comments Controller

class CommentsController < ApplicationController
  before_filter :authenticate_user!

  def new
  @post = Post.find(params[:post_id])
  @comment = Comment.new
  end


  def create
    @post = Post.find_by_id(params[:post_id])
    @comment = @post.comments.create(params.require(:comment).permit(:commenter, :body))
    @comment.user = current_user

    respond_to do |format|
      if @comment.save
        format.html { redirect_to @post, notice: 'Comment was successfully created.' }
        format.json { render json: @comment, status: :created, location: @comment }
      else
        format.html { render action: "new" }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end

  end

def destroy
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.destroy
    redirect_to post_path(@post)
end

def show
  @comment = Comment.new
end


private
  def comment_params
    params.require(:comments).permit(:commenter, :body)
  end

end*

View / _comments

<%= div_for(comment) do %>
    <p>
        <strong>Posted <%= time_ago_in_words(comment.created_at) %> ago</strong></br>
        <%= h(comment.body) %>
        <%= @comment.user.name %>
        <%= link_to 'Delete', [@post, comment], :method => :delete, :confirm => "Are you sure?" %>
    </p>
<% end %>

User Model

has_many :comments

Comment Model

class Comment < ActiveRecord::Base
    belongs_to :post
    belongs_to :user
end

Upvotes: 1

Views: 1027

Answers (4)

Joel
Joel

Reputation: 4593

In your comments controller your should your create method should look like this:

def create
@comment = current_user.comments.new(comment_params)

respond_to do |format|
  if @comment.save
    format.html { redirect_to @comment, notice: 'Comment was successfully created.' }
    format.json { render :show, status: :created, location: @comment }
  else
    format.html { render :new }
    format.json { render json: @comment.errors, status: :unprocessable_entity }
  end
 end
end

Then in your view/_comments file you should have something like this:

 Added:<%= time_ago_in_words(comment.created_at) %> ago<br>
 Added by: <%= current_user.email  %>

Let me know if this helps

Upvotes: 1

Annette
Annette

Reputation: 317

I was able to resolve this. <%= current_user.name %> needed to be in my _comment view and I removed @comment.user = current_user from my Comments Controller. Thank you all for your help.

View / _comments.html

<%= div_for(comment) do %>
    <p>
        <strong>Posted <%= time_ago_in_words(comment.created_at) %> ago</strong></br>
        <%= h(comment.body) %>
        <%= current_user.name %>
        <%= link_to 'Delete', [@post, comment], :method => :delete, :confirm => "Are you sure?" %>
    </p>
<% end %>

Comment Controller

class CommentsController < ApplicationController
  before_filter :authenticate_user!

  def new
  @post = Post.find(params[:post_id])
  @comment = Comment.new
  end


  def create
    @post = Post.find_by_id(params[:post_id])
    @comment = @post.comments.create(params.require(:comment).permit(:commenter, :body))

    respond_to do |format|
      if @comment.save
        format.html { redirect_to @post, notice: 'Comment was successfully created.' }
        format.json { render json: @comment, status: :created, location: @comment }
      else
        format.html { render action: "new" }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end

  end

def destroy
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.destroy
    redirect_to post_path(@post)
end

def show
  @commment = Comment.find params[:id]
end

Upvotes: 0

Inkling
Inkling

Reputation: 3782

<%= @comment.user.name %> should be <%= comment.user.name %> (no @ before comment), because that view/partial is using a local variable at that point, not an instance variable.

Just a tip for your question: you should give a little more context for the view snippet. Is it a full view, a part of a view, or a partial? What's its filename/which controller action does it map to? If it's a partial, which view is it being rendered from?

Upvotes: 0

Puhlze
Puhlze

Reputation: 2614

With the Rails / REST convention, the show action is responsible for rendering a representation of a specific resource instance. To do that it takes an id from params, looks up resource instance by the id, and renders a response. Your show action should load an existing comment, rather than creating a new comment. A new comment won't have a user assigned, which is why you are getting an error for calling a method on a nil object - the user for the new comment has not been set.

In your show action try the following:

@commment = Comment.find params[:id]

Upvotes: 0

Related Questions