Devise Authentication in Rails 3


Hi folk, We are writing step by step devise authentication for a sample app over rails 3.2.3 and ruby 1.9.3.

 

To create the application, you can cut and paste the code from the blog into your console ELSE do git clone rails_3_devise app and get real time experience with device. 


1. Creates a new Rails app named rails_3_devise on your computer. Type the below command.

 

$ rails new rails_3_devise –d mysql

 

Use the flag  –d mysql specify mysql as database, As we know rails having default sqlite db.

Now we move to app by typing 


$ cd rails_3_devise –d mysql

 

2. Finally we have to push our code to github, So doing some basic cammand to initialize git and pushing code to github  .
$ git init
Initialized empty Git repository in /home/maisa/workspace/rails_3_devise/.git/
$ git add .
$ git commit -m “First commint” 

 

3. Once we make sure our app is working

 

 

$ rails s -p 4000 

 

And check from browser http://localhost:4000/

 

4. Set Up Authentication, First things first, add “devise” to your rails Gemfile in the root directory of your application And do

 

$ bundle update

Fetching gem metadata from https://rubygems.org/………

Using warden (1.1.1)

Using devise (2.1.0)

Using jquery-rails (2.0.2)

Using rails (3.2.3)

Using sass (3.1.18)

 

We will see latest devie 2.1.0 has installed

 

Now following the install docs on the Devise project page. And run

 

$ rails g devise:install

create  config/initializers/devise.rb

create  config/locales/devise.en.yml

===============================================================================

 

Some setup you must do manually if you haven’t yet:

 

1. Ensure you have defined default url options in your environments files. Here

is an example of default_url_options appropriate for a development environment

in config/environments/development.rb:

 

config.action_mailer.default_url_options = { :host => ‘localhost:3000’ }

 

In production, :host should be set to the actual host of your application.

 

2. Ensure you have defined root_url to *something* in your config/routes.rb.

For example:

 

root :to => “home#index”

 

3. Ensure you have flash messages in app/views/layouts/application.html.erb.

For example:

 

<p><%= notice %></p>

<p><%= alert %></p>

 

4. If you are deploying Rails 3.1 on Heroku, you may want to set:

 

config.assets.initialize_on_precompile = false

 

On config/application.rb forcing your application to not access the DB

or load models when precompiling your assets.

 

===============================================================================

 

Alright, based on the install output it looks like we need to do a little setup work… Make sure we are following all above instruction.

After you are finished configuring the application its time to create your user model.

$ rails generate devise User

invoke  active_record

create    db/migrate/20120516110556_devise_create_users.rb

create    app/models/user.rb

invoke    test_unit

create      test/unit/user_test.rb

create      test/fixtures/users.yml

insert    app/models/user.rb

route  devise_for :users

 

Great, lets take a look at what the generator created starting with the migration.

 

class DeviseCreateUsers < ActiveRecord::Migration

def change

create_table(:users) do |t|

## Database authenticatable

t.string :email,              :null => false, :default => “”

t.string :encrypted_password, :null => false, :default => “”

 

## Recoverable

t.string   :reset_password_token

t.datetime :reset_password_sent_at

 

## Rememberable

t.datetime :remember_created_at

 

## Trackable

t.integer  :sign_in_count, :default => 0

t.datetime :current_sign_in_at

t.datetime :last_sign_in_at

t.string   :current_sign_in_ip

t.string   :last_sign_in_ip

 

## Confirmable

# t.string   :confirmation_token

# t.datetime :confirmed_at

# t.datetime :confirmation_sent_at

# t.string   :unconfirmed_email # Only if using reconfirmable

 

## Lockable

# t.integer  :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts

# t.string   :unlock_token # Only if unlock strategy is :email or :both

# t.datetime :locked_at

 

## Token authenticatable

# t.string :authentication_token

 

 

t.timestamps

end

 

add_index :users, :email,                :unique => true

add_index :users, :reset_password_token, :unique => true

# add_index :users, :confirmation_token,   :unique => true

# add_index :users, :unlock_token,         :unique => true

# add_index :users, :authentication_token, :unique => true

end

end

 

Now let’s take a look at our User model.


class User < ActiveRecord::Base

# Include default devise modules. Others available are:

# :token_authenticatable, :confirmable,

# :lockable, :timeoutable and :omniauthable

devise :database_authenticatable, :registerable,

:recoverable, :rememberable, :trackable, :validatable

 

# Setup accessible (or protected) attributes for your model

attr_accessible :email, :password, :password_confirmation, :remember_me

# attr_accessible :title, :body

end

 

We don’t need to setup our routes for user because devise has already added devise_for :users to our config/routes.rb for us. If we then run rake routes from the command line we get:

 

$ rake routes user
              home_index GET    /home/index(.:format)          home#index
        new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
           user_password POST   /users/password(.:format)      devise/passwords#create
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
                         PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
       user_registration POST   /users(.:format)               devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy
                    root        /                              home#index

Finally it’s time to migrate our database and create our user model.

$ rake db:migrate

==  DeviseCreateUsers: migrating ==============================================

— create_table(:users)

-> 0.0175s

— add_index(:users, :email, {:unique=>true})

-> 0.0010s

— add_index(:users, :reset_password_token, {:unique=>true})

-> 0.0012s

==  DeviseCreateUsers: migrated (0.0202s) =====================================

 

5. Now let’s create a Home Page and add custom message to index page

 

$ rails generate controller home index –no-controller-specs      create  app/controllers/home_controller.rb

route  get “home/index”

invoke  erb

create    app/views/home

create    app/views/home/index.html.erb

invoke  test_unit

create    test/functional/home_controller_test.rb

invoke  helper

create    app/helpers/home_helper.rb

invoke    test_unit

create      test/unit/helpers/home_helper_test.rb

invoke  assets

invoke    coffee

create      app/assets/javascripts/home.js.coffee

invoke    scss

create      app/assets/stylesheets/home.css.scss

 

And remove default public index page, As we expecting home/index will be our default page.

 

$ rm public/index.html

And will add root url to routes.rb file  and protect user controller adding  

 

before_filter :authenticate_user!

 

At top of index action.

 

root :to => “home#index”

 

 

 

Now  we almost done. Finally we need to create  an Application Layout with few login, logout,sign links. For that we Create a shared directory under app/views/. Then create the file app/views/shared/_navigation.html.erb and add:

 

<% if user_signed_in? %>

<li>

<%= link_to(‘Logout’, destroy_user_session_path, :method=>’delete’) %>

</li>

<% else %>

<li>

<%= link_to(‘Login’, new_user_session_path)  %>

</li>

<% end %>

<% if user_signed_in? %>

<li>

<%= link_to(‘Edit account’, edit_user_registration_path) %>

</li>

<% else %>

<li>

<%= link_to(‘Sign up’, new_user_registration_path)  %>

</li>

<% end %>

 

Then use these partials in your app/views/layouts/application.html.erb file, like this:

 

<ul>
<%= render ‘shared/navigation’ %>
</ul>
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => “flash_#{name}” if msg.is_a?(String) %>
<% end %>
<%= yield %>

 

Now Add stylesheet rules to the application.css.scss file:

 

header nav ul {
list-style: none;
margin: 0 0 2em;
padding: 0;
}
header nav ul li {
display: inline;
}
#flash_notice, #flash_alert {
padding: 5px 8px;
margin: 10px 0;
}
#flash_notice {
background-color: #CFC;
border: solid 1px #6C6;
}
#flash_alert {
background-color: #FCC;
border: solid 1px #C66;
}

 

That all coding part.  

 

Now it’s time to start our rails server and see what devise has given us. Run rails server from the command line and lets travel to “localhost:4000/

 

That’s expected. As we protected our home page. Now we need to sign_up and post sign_in. After using right credentials we will see

 

 

 

 

 

Thanks, Enjoy……………….

Advertisements

10 thoughts on “Devise Authentication in Rails 3

  1. Meow says:

    It worked well ..thanks, I had the problem of signing out and returning to the signin page, so I followed these instructions and it worked 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s