Blog › Ruby

Two step signup with Devise

[** UPDATE: 21/01/2013 **]: Thanks to Kevin Triplett now there's a Devise wiki page referencing this post and combining the comments. Please check this wiki page, especially if you’re using Rails 3 and Devise 2:
https://github.com/plataformatec/devise/wiki/How-To:-Email-only-sign-up

On my Ruby on Rails projects I usually use the Devise gem for user authentication.

In the last application I need to customize Devise so that users can register providing email address only. I will ask for a password only at the confirmation step.
After some tests, I come with this solutions.

1. First I need to overwrite the ConfirmationsController, so in the routes.rb I set devise to use my custom controller (my model is called Account).
I also need to define a custom controller for registrations so I can customize the registration view:


devise_for :accounts, :controllers => {:confirmations => "confirmations", :registrations => "registrations"} do
put "confirm_account", :to => "confirmations#confirm_account"
end

As you can see I've also added a custom method, confirm_account that I will use in the fourth step, as you will see soon.

2. Now I need to skip the devise built in password validation.
To achieve this I wrote a custom initializer called devise_customization.rb in /config/initalizers/ like this:


module Devise
module Models
module Validatable

def password_required?
false
end

 

 end
end
end

So I have overwritten the default devise validatable module skipping the password validation.

3.The next step is to customize views.
Given I'm using a custom ConfirmationsController and RegistrationsController I have copied the default confirmations views under /views/confirmations/ and the default registrations views under /views/registrations/ and changed them according to my two step registration.

The /registrations/new view is something like this (I'm using haml)


= form_for(resource, :as => resource_name, :url => account_registration_path(@account)) do |f|
= devise_error_messages!
%p
= f.label :email
= f.email_field :email
%p.clearfix
= f.submit 'Signup'
= link_to 'Home', root_url
%br/
= render :partial => 'devise/shared/links'

Here I've just remove the password and password_confirmation fields.

The /confirmations/show view is something like this


= form_for(resource, :url => confirm_account_path) do |f|
= devise_error_messages!
%p
= f.label :email
= @account.email
= f.hidden_field :confirmation_token
%p
= f.label :password
%br/
= f.password_field :password
%p
= f.label :password_confirmation
%br/
= f.password_field :password_confirmation
%p.clearfix
= f.submit 'Confirm Account'
= link_to 'Home', root_url
%br/
= render :partial => 'devise/shared/links'

4. Ok, once I've setup the views I have to write the new confirmation method in my ConfirmationsController. I can leave unchanged the RegistrationsController.


class ConfirmationsController < Devise::ConfirmationsController
def show
@account = Account.find_by_confirmation_token(params[:confirmation_token])
if !@account.present?
render_with_scope :new
end
end

def confirm_account
@account = Account.find(params[:account][:confirmation_token])
if @account.update_attributes(params[:account]) and @account.password_match?
@account = Account.confirm_by_token(@account.confirmation_token)
set_flash_message :notice, :confirmed
sign_in_and_redirect("account", @account)
else
render :action => "show"
end
end

 

end

The show method simply find the account to confirm by the devise token and render the show view.
The key point is the confirm_account method where I find the account, update attributes and if password_match? return true I confirm the account calling the standard devise method confirm_by_token

5. The last thing to do is to define the password_match? method inside the Account model.


class Account < ActiveRecord::Base
...

def password_match?
self.errors[:password] << 'password not match' if password != password_confirmation
self.errors[:password] << 'you must provide a password' if password.blank?
password == password_confirmation and !password.blank?
end

 

end

That's all!
Now you can star your rails server and signup in your application providing a password only at the confirmation step.

Find out where AI can save your company time.

One hour with our team: we map your processes, pick 2-3 concrete use cases and tell you what is worth doing first. No strings attached.

Book a free AI assessment
Subsidised finance

Incentives and grants for your software or AI project.

With specialised partners we check which incentives your project can access and prepare the paperwork and the financing plan.

  • Hyper-depreciation for 4.0 and 5.0 assets
  • National and regional grants
  • Financing plan
Book a free AI assessment