Reputation: 231
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
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
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
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
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