react-devise
react-devise copied to clipboard
Support for user profile route w /users/:user_id ?
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
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.
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
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.
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!
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.