I'm using Devise in a Rails 3 app, but in this case, a user must be created by an existing user, who determines what permissions he/she will have.
Because of this, I want:
- To remove the route for users to sign up.
- To still allow users to edit their profiles (change email address and password) after they have signed up
How can I do this?
Currently, I'm effectively removing this route by placing the following before devise_for :users
:
match 'users/sign_up' => redirect('/404.html')
That works, but I imagine there's a better way, right?
Update
As Benoit Garret said, the best solution in my case is to skip creating the registrations routes en masse and just create the ones I actually want.
To do that, I first ran rake routes
, then used the output to re-create the ones I wanted. The end result was this:
devise_for :users, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
Note that:
- I still have
:registerable
in myUser
model devise/registrations
handles updating email and password- Updating other user attributes - permissions, etc - is handled by a different controller
Actual answer:
Remove the route for the default Devise paths; i.e.:
devise_for :users, path_names: {
sign_up: ''
}
You could modify the
devise
gem itself. First, run this command to find the installed location of using:gem which devise
Let's suppose the path is:
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise
Then go to
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise/lib/devise/rails
and editroutes.rb
in that directory. There is a method calleddef devise_registration(mapping, controllers)
which you can modify to get rid of the new action. You can also completely remove the mappings fordevise_registration
I tried to do this as well, but a thread on the devise google group dissuaded me from searching for a really clean solution.
I'll quote José Valim (the Devise maintainer) :
The original question was :
I had similar issue tried to remove devise_invitable paths for create and new :
before:
rake routes
after
rake routes
note 1 devise scope https://github.com/plataformatec/devise#configuring-routes
note 2 I'm applying it on devise_invitable but it will work with any devise *able feature
Important note: see that devise_scope is on user not users ? that's correct, watch out for this ! It can cause lot of pain giving you this problem:
Here's the slightly different route I went. It makes it so you don't have to override the
devise/shared/_links.html.erb
view.In
app/models/user.rb
:In
config/routes.rb
:Before:
After:
You can override the "devise_scope" by placing it before the "devise_for".
Not sure if this is the best way but its my solution currently, as it just redirects back to the sign in page.
I've found this to work well without messing with routes or adding application controller methods. My approach is to override the devise method. Add this to
app/controllers/devise/registrations_controller.rb
I've omitted the other methods for brevity.Also to remove illusion that this path is still reachable from other views you might also want to remove this code from
app/views/devise/shared/_links.erb