I am slowly learning rails by doing and testing things, but i have run into a block. I have a simple rails 3.1 app and have a simple user register/sign in process working. I am not using devise because i would rather learn how to do it myself.
Currently a user can register, sign in and sign out. But I want them to be able to edit their profile. At present any user can go to users/1/edit/ even if their ID isn't set to 1. How do i check to see if the current_user matches that of the url? I know i need some sort of before filter on the edit action of my users_controller.
Here is what i have at present
users_controller.rb
before_filter :is_owner, :only => [:edit, :update, :destroy]
application_controller.rb
helper_method开发者_开发问答 :is_owner
def is_owner
end
What should be in my is_owner function?
I'm guessing your problem resides in getting the parameter from the URL. This could be done with the params array:
params[:id]
With that (depending on your routing configuration!), you could do something like
def is_owner?
current_user.id == params[:id]
end
Fuzzyalej is apparently a faster typer than me ;-), so I can only suggest you some more verbose form of the function. (His answer is absolutely correct)
You have defined the filter method in ApplicationController, but in this case comparing just the 'id' parameter may be misleading, since in other actions the 'id' may describe a document (for example) instead of an user. It may be safer if you define the filter function in the UsersController (just make it a private function)
Personally, I often put similar rules directly in the actions, but using a filter may be more DRY.
I would define the methods 'edit', 'update' and 'destroy' in this way: (maybe you will like it)
def edit # and 'update', and 'destroy'
@user = User.find(params[:id])
render_forbidden and return unless can_edit?
# ...and the rest of the action
end
private
def can_edit?
current_user.is_admin? || current_user == @user
end
# This one usually is defined in ApplicationController, as I use it often
def render_forbidden
respond_to do |format|
format.html { render :action => "errors/forbidden", :status => 403 }
#...
end
true
end
精彩评论