开发者

Rails 3.1 only user can edit their profile

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜