react-devise icon indicating copy to clipboard operation
react-devise copied to clipboard

Support for user profile route w /users/:user_id ?

Open bhellman1 opened this issue 7 years ago • 5 comments

Hello, given the way react-devise handle the user routes, is it possible to support a user profile route? Something like:

<PrivateRoute path="/users/:user_id" layout={MainLayout} component={User} />

Currently the above will cause the browser to redirect/loop and crash. Thanks

bhellman1 avatar Aug 14 '17 15:08 bhellman1

Before I try to answer, are you're wanting to allow to current user to edit his own profile, or are you talking about an admin interface where an admin can edit other users? Based on the path (which includes :user_id), it seems like the latter, but I'm not sure.

timscott avatar Aug 14 '17 15:08 timscott

More like a public profile for a user (not for editing or admin)... Example: https://twitter.com/007 ---

Where in this case it would be: http://site.com/users/1 -- where 1 is the user_id

bhellman1 avatar Aug 14 '17 15:08 bhellman1

Whatever you do, you will not want the current user's own ID in the URL.

You could handle one of two ways: roll your own, or leverage Devise.

Roll Your Own

You could create a private route, as you have shown, and then create something like UserProfileController in your Rails server. Except for making the route private, react-devise and devise itself plays no part in this. Because /users is used by react-devise, you should either choose a different route (e.g., /user-profile) or cancel the react-devise route:

initReactDevise({
  // other config
  routes: {
    editUser: undefined
  }
});

Leverage Devise

The advantage of this approach is that Devise will handle things like reconfirmation of email address.

Just now I have published v0.0.15, which has additional support for this second approach. There is a new client side route named editUser with url of /users. By default this route uses a new view component User. The default view has only one field, namely email. You probably want to use your own custom view instead, which will allow you to edit any user attributes:

initReactDevise({
  // other config
  routes: {
    editUser:{
      component: MyUserProfileComponent
    }
  }
});

Devise has a couple of issues that require some tweaking on the server to make this work. The solution is to create a custom RegistrationsController controller, like this:

class RegistrationsController < Devise::RegistrationsController
  def edit
    respond_with resource
  end

protected

  def update_resource(resource, params)
    if params[:password].present?
      resource.update_with_password params
    else
      resource.update_without_password params
    end
  end
end

The overriden #edit method solves an issue with Devise.

The overidden #update_resource method is only needed if you want to omit password fields. This is an existing limitation with Devise.

Configure the routes to use your custom controller:

# config/routes.rb

devise_for :users, path: :auth, controllers: {registrations: :registrations}

One other thing to note. As discussed in this issue, when the user is updated, you will not get back an updated auth token. If you are storing user info in that token, it will become stale. You can configure devise-jwt to correct this if you want. See the aforementioned issue to see how.

timscott avatar Aug 14 '17 21:08 timscott

re: "Whatever you do, you will not want the current user's own ID in the URL." - why is that? StackOverflow for example does such a thing: https://stackoverflow.com/users/70157/bignose

This is all super helpful - thank you!

bhellman1 avatar Aug 15 '17 03:08 bhellman1

run rake routes. You will see that the registration edit route does not contain the user's ID. Nor does the registration update route. It's redundant to have the current user's id in the URL. There's only one current user, and you have his identity in session (in our case, auth token).

It's different if you are exposing a users' profiles to one another in a social app. Then you need an identity in the URL to know which user to show.

timscott avatar Aug 15 '17 04:08 timscott