A Sense of Belonging
Friday, August 29th, 2008Numerous times I’ve needed and I’ve seen other people have needed the need to check whether an object belongs to the currently logged in user. I’ve worked out that something like this works:
class User < ActiveRecord::Base
hasmany :posts
def owns?(object)
object.user == self
end
end
This works when you have a currently logged in user and call it by using currentuser.owns?(@post). Now what if you wanted to do it the other way around? Well it’s really as simple as this:
class Post < ActiveRecord::Base
belongsto :user
def belongsto?(otheruser)
user == otheruser
end
end
Now you can reference that through @post.belongsto?(otheruser).
If you wanted to use either of these in the controller, it would be like this:
class PostsController < ApplicationController
def edit
@post = Post.find(params[:id])
check_ownership
end
def update
@post = Post.find(params[:id])
if currentuser.owns?(@post) # or @post.belongsto?(currentuser)
# carry on...
if @post.updateattributes(params[:post])
flash[:success] = "Post updated!"
redirectto topicpath(@topic)
else
flash[:error] = "Post could not be updated."
render :action => "edit"
end
else
flash[:error] = "You do not own that post."
end
end
private
def checkownership
if !currentuser.owns?(@post) # or @post.belongsto?(currentuser)
flash[:error] = "You do not own that post!"
redirectbackordefault topicpath(@topic)
end
end
end
Now here we’ve called checkownership in the edit action which will stop the template from being rendered by calling redirectbackordefault. We can’t call (as I found out thanks to BlueSea) checkownership in the same way in the update action because the code will still be executed. So we must call the methods we defined in the model, either currentuser.owns?(@post) or @post.belongsto?(current_user).
