(Semi-newbie.) I want to ensure a user’s able to destroy only his own
objects. I’ve set session info at login:
session[:user_id] = user.id
Now I try this in the model of my deletable objects:
before_destroy :destroy_your_own
def destroy_your_own
raise “Can’t delete that!” unless session[:user_id] == self.user.id
end
which snags EVERY attempted destroy. What am I doing wrong? Better
ideas?
It’s hard to say without seeing the rest of the code, but have you
tested the value of self.user.id within the method? My guess is that
self.user.id is nil and thus the error is always raised.
Justin S. wrote:
(Semi-newbie.) I want to ensure a user’s able to destroy only his own
objects. I’ve set session info at login:
session[:user_id] = user.id
Is the session cookie secure? How easy is it to forge a sessionn with
someone else’s user.id?
–Dean
Models don’t have access to the session, so session[:user_id] is nil.
Sessions are a controller thing. One way I’ve seen this work is this:
- Add a ‘current_user’ class property to your User model
- Create a before_filter that sets this to the session[:user] on every
request (not just at login)
- In your model code, use ‘User.current_user’ instead of session[:user]
I wouldn’t even take the callback/filter route. I’d simply define my
own method, destroy_as:
class SomeModel < ActiveRecord::Base
def destroy_as(user)
return false unless self.user == user
destroy
end
end
now the controller - presumably you
have access to the user object, not just
the id - i usually instantiate a user from
an id in the session using a before_filter
def destroy
@obj = SomeModel.find(params[:id]
if @obj.destroy_as(@current_user)
flash[:notice] = ‘It worked!’
else
flash[:error] = ‘It didnt work!’
end
end
Hope that helps. You could alternatively just pass in the user ID to
destroy_as and do the comparison that way but I think this is more
intention revealing.