pcasa
pcasa

Reputation: 3730

Force current_user path

Currently users can access their "profile" through many paths.

How can I make it that they can only get to their "profile" through localhost:3000/users/current_user

Upvotes: 0

Views: 837

Answers (2)

whazzmaster
whazzmaster

Reputation: 576

One suggestion on the 'what' of your question: instead of the ideal url being localhost:3000/users/current_user I suggest localhost:3000/user or something even more descriptive such as localhost:3000/profile or localhost:3000/account.

Could you include the entries in your routes.rb? Even if Authlogic, etc. add routes to your app, they should do it in routes.rb. If you have the entry:

map.resource :users

then that's where the /users/123 route is coming from. I agree with Matchu that even if you don't use /users/123 you should keep it and route other requests to it.

An Additional Idea If you don't want to get into the (kinda complicated, and not pretty) business of preserving model validation errors across redirects, here's another way. I'm assuming from here that you already have map.resource :users, so that you have the 7 default actions on your UsersController (index, new, create, show, edit, update, destroy).

In your routes.rb:

map.profile 'profile', :controller => 'users', :action => 'show'
map.edit_profile 'profile/edit', :controller => 'users', :action => 'edit', :conditions => { :method => :get }
map.update_profile 'profile/edit', :controller => 'users', :action => 'update', :conditions => { :method => :put }

You will need to update your form_for tag slightly:

<% form_for @user, :url => update_profile_path do |f| %> ...

Now, assuming you start on /profile, and click an edit link that takes you to /profile/edit (should show the form), if you fill out the form such that it fails validation then you should end up back on /profile/edit with the correct errors in the f.error_messages output.

Your controller code for edit should stay the same, and your code for update should be:

def update
   @user = current_user || User.find(params[:id])
   if @user.update_attributes(params[:user])
     flash[:notice] = "Successfully updated user."
     redirect_to @user
   else
     render :action => 'edit'
   end
end

The render (rather than a redirect) preserves the state of the @user model (including errors) and just renders the edit template again. Since you directed it at the update_profile_path the url viewed by the user is still /profile/edit.

Upvotes: 1

Matchu
Matchu

Reputation: 85792

Umm, first, remove the /users/current route that you must have in your routes.rb somewhere. (Although I prefer /users/current to /users/current_users, since the latter is rather redundant.)

As for /users/123, in your controller, you can check if the current user's ID matches 123 or whatever, and, if so, redirect.

But I really prefer the opposite effect. Pushing /users/current to /users/123 makes more sense in my brain, since it keeps the routes consistent for all users while still allowing you to cache links to /users/current.

Upvotes: 0

Related Questions