PMP
PMP

Reputation: 231

Rails User Association with comments

I have a User scaffold (DEVISE), a Comments scaffold and a movies scaffold

Currently, Comments are posted on the movie show page.

What i'm having trouble with is having the comment be created by User. So that a comment is create by a User.

So if i display the comment in the movies/:show

I could do

Body: <%= comment.body %> Author: <%= comment.user.first_name %>

How would I make a comment belong to a user, and only editable and destroy-able BY that user only?

Please dont tell to use before_filter :authenticate_user!, only: [:create,:destroy] or follow the Michael Hartl Tutorial with Microposts because I have already done both of these and they dont work

Anyways, does anyone know how I could do this?

MAny Thanks

Upvotes: 1

Views: 2142

Answers (4)

rmagnum2002
rmagnum2002

Reputation: 11421

first I would show the edit and destroy link only to owner with:

<% if comment.user == current_user %>
  <%= link_to "edit", ... %>
  <%= link_to "delete", ... %>
<% end %>

and then just in case for smart guys who knows how to use inspect element in chrome, I would do a controller level check for comment owner:

def edit
  @comment = Comment.find(params[:id])
  if @comment.user == current_user
    @comment.update_attributes(....)
    @message = "Comment updated or created or deleted, depends on method"
  else
    @message = "It's not your comment wise guy :)"
  end
  redirect_to :back, notice: @message
end

the same for destroy and update method.

!not a copy/paste ready code.

this is what I did once and it worked quite nice, other method you can use gem cancan https://github.com/ryanb/cancan and set abilities for users.

can :edit, Comment, :user_id => user.id
can :destroy, Comment, :user_id => user.id

with setting abilities this way only owner will be able to access edit page and the update, destroy actions.

Upvotes: 3

Alexander Kobelev
Alexander Kobelev

Reputation: 1379

what's about devise helper 'current_user'? something like this:

class Comment < ActiveRecord::Base
  belongs_to :user
end

class CommentsController < ApplicationController
  def edit
    comment = current_user.comments.where(id: params[:id]).first
    if comment.nil?
      ...
      401 error or something else (current user is not creator of this comment)
    else
     ...
    end
   end
end

And also you can check permissions in view:

<% if comment.user == current_user %>
  <%= link_to "edit comment" ... %>
  <%= link_to "delete comment" ... %>
<% end %>

Upvotes: 1

Martin M
Martin M

Reputation: 8638

Making sure that a user is signed in with :authenticate_user! is a good thing, but you have to associate the comment with th user too.

Devise gives you a current_user. So if your Comment belongs_to :user and your User has_many :comments write in your CommentsController:

def new
  @comment= current_user.comments.new
end

def create
  @comment= current_user.comments.new(params[:comment])
  if @comment.save
    ...
  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(params[:comment])
    ...
  end
end

Upvotes: 0

Marek Lipka
Marek Lipka

Reputation: 51151

To make the comment belongs to user, in your create action:

comment = current_user.comments.new(params[:comment])

To make it editable/destroyable only for owner

before_filter :find_comment, only: [:show, :edit, :update, :destroy]
before_filter :authorize_user!, only: [:edit, :update, :destroy]
#...

private

  def find_comment
    @comment = Comment.find params[:id]
  end

  def authorize_user!
    deny_access if @comment.user != current_user # example
  end

Upvotes: 0

Related Questions