Probably there are not many cases where one wouldn't wont their users to have email addresses. Nevertheless, I had exactly this situation recently. It was quite a challenge (for me at least) to figure out all the things one needs to change in Devise, so as not to expect users to provide an email upon registration and sign-in and to work properly. Finally, I was able to set it to work properly and decided to save you the trouble, in case some of you have a similar setup.
Allow normal users to authenticate with username only, while keeping email authentication for admins in ActiveAdmin
You are using ActiveAdmin (AA), Devise, Rails 4 and Ruby 2. You have two models/AA resources - AdminUsers (created by default after installing AA) and Users (generated using Devise). You want your users to be able to login only with username and not have the email attribute at all. At the same time you want your admins to be able to log-in in the AA backend via email.
You can view the source on Github.
I refer to the files unser
app/models/ as models and the files under
app/admin/ as resources.
- Generate a new Rails application:
- Add to Gemfile
- Install gems:
- Install ActiveAdmin:
- Migrate the database:
So far you should have a working app with an admin backend, containing an AdminUsers resource. Test it by starting the server with
rails s, going to
http://localhost:3000/admin and logging in with credentials
Now comes the real work of generating your user model and doing a few tweaks.
Modify the Devise initializer under
config/initalizers/devire.rb. In particular, change the following lines to look like this:
We we will leave the line:
commented out, as we don't want to change the authentication keys globally. We want our admin users to still be able to log in with email. We will change the authentication keys only within the user model.
config.scoped_views and set it to
We need this because we have more than one Devise model (AdminUsers and Users) and we want to modify the Users views. More info here.
Generate the User model:
In the user migration file under
:username so that you have the folloing two lines in the file:
Tweak the User model:
- set the desired Devise modules;
- add the authentication keys option;
Your model should look something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
I have not included
:recoverable as I want all my user management to happen on the backend through ActiveAdmin. What's more, as the User model does not have the email attribute, these modules won't work anyway.
Finally, run the migration:
Register the User model as a resource in ActiveAdmin:
Modify the User resource to look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
The Devise views need to be modified in order to reflect that the user is using their username and not their email. First, generate them:
Since I have not included the
:recoverable modules, the only relevent view is
app/views/devise/sessions/new.html.erb. You only need to change these lines:
f.email_field needs to be changed to
f.text_field, otherwise in newer browsers the built-in validation won't pass and you'll get error when you enter a username in that field.
To test your work:
- create a new user via the admin back-end;
- go to
http://localhost:3000/users/sign_inand log in.
Bear in mind that if you have not created a default home page containing a sign out link, you won't be able to log out by just entering
http://localhost:3000/users/sign_out by default, as the sign-out route uses the
:delete HTTP method. As a temporary workaround, in the Devise initializer set
:get and in
devise_for :users to
I hope I have saved you some time.