AnthonyGalli.com
AnthonyGalli.com

Reputation: 2866

How to add user name to comment?

When a User creates a comment. How can we add his name to it? I tried current_user but that obviously just state's the current user's name instead of the name of the person who made the comment.

In User model has_many :comments, as: :commentable in comment model belongs_to :commentable, polymorphic: true which in routes is broken down with resources :users do resources :comments end.

views/comments/_comments.html.erb

<div id="comments">
<% @comments.each do |comment| %>
    <div class="comment">
        <%= current_user.name %>
        <%= simple_format comment.content %>
    </div>
<% end %>

comments controller

class CommentsController < ApplicationController
	before_action :load_commentable
  before_action :set_comment, only: [:show, :edit, :update, :destroy]
  before_action :logged_in_user, only: [:create, :destroy]

	def index
		@comments = @commentable.comments
	end

	def new
		@comment = @commentable.comments.new
	end

	def create
		@comment = @commentable.comments.new(comment_params)
		if @comment.save
			@comment.create_activity :create, owner: current_user 
			redirect_to @commentable, notice: "comment created."
		else
			render :new
		end
	end

	def edit
		@comment = current_user.comments.find(params[:id])
	end

	def update
		@comment = current_user.comments.find(params[:id])
		if @comment.update_attributes(comment_params)
			redirect_to @commentable, notice: "Comment was updated."
		else
			render :edit
		end
	end

	def destroy
		@comment = current_user.comments.find(params[:id])
		@comment.destroy
		@comment.create_activity :destroy, owner: current_user
		redirect_to @commentable, notice: "comment destroyed."
	end

private
  def set_comment
    @comment = Comment.find(params[:id])
  end

	def load_commentable
		resource, id = request.path.split('/')[1, 2]
		@commentable = resource.singularize.classify.constantize.find(id)
	end

	def comment_params
		params.require(:comment).permit(:content, :commentable)
	end
end

I made showing various names in the activity feed work by creating a controller. Are there principles in here I could take to make it work because I've tried and failed.

class ActivitiesController < ApplicationController
 def index
 @activities = PublicActivity::Activity.order("created_at desc").where(owner_id: current_user.following_ids, owner_type: "User")
 end
end

users migrations

class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
  t.string   :name
  t.string   :email
  t.string   :provider
  t.string   :uid
  t.string   :oauth_token
  t.datetime :oauth_expires_at

  t.timestamps null: false
end
end
end

comments migration

class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
    t.text :content
    t.belongs_to :commentable, polymorphic: true

  t.timestamps null: false
end
add_index :comments, [:commentable_id, :commentable_type]
end
end

valuations_controller

class ValuationsController < ApplicationController
  before_action :set_valuation, only: [:show, :edit, :update, :destroy]
  before_action :logged_in_user, only: [:create, :destroy]

  def index
    if params[:tag]
      @valuations = Valuation.tagged_with(params[:tag])
    else
      @valuations = Valuation.order('RANDOM()')
    end
  end

  def show
    @valuation = Valuation.find(params[:id])
    @commentable = @valuation
    @comments = @commentable.comments
    @comment = Comment.new
  end

  def new
    @valuation = current_user.valuations.build
    @commentable = @valuation
    @comments = @commentable.comments
    @comment = Comment.new
  end

  def edit
  end

  def create
    @valuation = current_user.valuations.build(valuation_params)
    if @valuation.save
      redirect_to @valuation, notice: 'Value was successfully created'
    else
      @feed_items = []
      render 'pages/home'
  end
end

  def update
    if @valuation.update(valuation_params)
      redirect_to @valuation, notice: 'Value was successfully updated'
    else
      render action: 'edit'
  end
end

  def destroy
    @valuation.destroy
    redirect_to valuations_url
  end

private
    def set_valuation
      @valuation = Valuation.find(params[:id])
    end

    def correct_user
      @valuation = current_user.valuations.find_by(id: params[:id])
      redirect_to valuations_path, notice: "Not authorized to edit this valuation" if @valuation.nil?
    end

    def valuation_params
      params.require(:valuation).permit(:name, :private_submit, :tag_list, :content, :commentable, :comment)
    end
end

Thank you for your time!

Upvotes: 1

Views: 1663

Answers (1)

Klaus
Klaus

Reputation: 1771

Assuming that you have

User model:

class User
  has_many :comments
  ...
end

Comment model

class Comment
  belongs_to :user
  ...
end

Comment migration

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.text :content
      t.belongs_to :user, index: true

      t.timestamps null: false
    end
  end
end

you can get the user's name of a comment by

@comment = Comment.find(params[:id])
@comment.user.name

EDIT: If you want to work with polymorphic associations, edit your models like this:

class User
  has_many :comments, as: :commentable
  ...
end

class Comment
  belongs_to :commentable, polymorphic: true
  ...
end

EDIT: Insert Comments migration

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.text :content
      t.references :commentable, polymorphic: true, index: true

      t.timestamps null: false
    end
  end
end

EDIT related to ValuationsController

  1. You are looking for the user who created a specific valuation comment. @valuation holds this comment. So you can get the user with @valuation.commentable.user.name - This assumes, that your Valuation sets the correct association to Comment model.

  2. Delete @commentable = @valuation and @comments = @commentable.comments. They are not wrong, but in that case it doesn't make any sense to hold variables with the same value.

  3. In the 'show' action you've assigend @comment with Comment.new. Delete this line, because you are not creating new objects in the show action.

  4. You've already assigned @valutation in the before_action at the top of your class with the same value. To prevent confusion, delete this additional assignment in the show action.

A clue for future debugging: If your code doesn't work as expected, try it running in the rails console. We've seen yesterday, that the code around @comment.commentable.user.name was correct. That showed me, that there must be something wrong in your controller.

Final Solution

Add <%= User.find(comment.user_id).name %> to _comments.html.erb

Upvotes: 2

Related Questions