Creating a simple Ruby on Rails application using Devise

If you have heard about rails and not yet experienced the power or features that , only rails can give !  this tutorial will help you to create a Simple Ruby on Rails application without worrying too much about the syntax or working of Ruby on Rails.

Here in this tutorial we will create a database backed simple Rails community website application, so that all members can register and sign-in to the website.

About Rails :

Rails is a web development frame work written in ruby language,which has a general MVC     ( Model, View, Controller ) architecture.Using a Rails framework will make everything effortless for the developers,who wants to build a powerful/fast application with a less set of code and rails will also help them to achieve more than any other framework can provide.

About Devise :

Simply Devise is a flexible authentication solution for Rails based on Warden. It:

  • Is Rack based.
  • Is a complete MVC solution based on Rails engines.
  • Allows you to have multiple roles (or models/scopes) signed in at the same time.
  • Is based on a modularity concept: use just what you really need.

Lets start coding:

We are going to create a simple rails community website with the help of devise,Before wr entering to our application you should have to gone through the basics of devise.please refer the following link if you want to learn more about devise and rails.

Installation :

I am using ubuntu 11.04, if you are using ubuntu you can follow the below link to install rails in your system.You can also install rails in windows or mac as well.

Creating your application :

Once you have installed every dependencies,you can start creating your first application in rails.

Use “rails new” command to create your application in rails,here we are going to create an application named rails-club.rails

$ rails new rails-club

$ cd rails-club

once you run the above command in your system, you can see that rails has generated so many files and folders inside your rails-club directory.

Editing the Gemfile :

We are going to create this application by using a devise, i have already told you that this is a database backed application.If you are using mysql as your database system then you have to edit your ‘Gemfile’ inside your rails-club directory and add the following line to your ‘Gemfile’.

$ gem 'mysql2', '0.3.6'

Once you have edited the Gemfile,please go through the files and directories the rails has generated,there is file called “database.yml “ in your “config” directory.Change the adapter to mysql2,and then specify your database,username and password . My “database.yml” file contains the following data.

Filepath : config/database.yml

development:
adapter: mysql2
encoding: utf8
reconnect: false
database: mydb
pool: 5
username: root
password: asdfgh

production:
adapter: mysql2
encoding: utf8
reconnect: false
database: mydb
pool: 5
username: root
password: asdfgh
socket: /var/run/mysqld/mysqld.sock

test:
adapter: mysql2
encoding: utf8
reconnect: false
database: mydb_testing
pool: 5
username: root
password: asdfgh
socket: /var/run/mysqld/mysqld.sock

Once you have done all the changes then run the “bundle install” command. This command tells “bundler”, a library used by Rails, to fetch and install all the libraries it needs.

$ bundle install

Installing Devise :

You can use the latest Rails 3 gem with the latest Devise gem, to install the Devise run the following command.

$ gem install devise

After you have installed Devise, you should have to specify the Devise gem to your Gemfile.

$ gem 'devise'

After that you need to run the generator by using the command below.

$ rails generate devise:install

The generator will install an initializer which describes ALL Devise’s configuration options and you MUST take a look at it. When you are done, you are ready to add Devise to any of your models using the generator.

Creating Models :

Here in this application we mainly needs 2 models,one is member model and the other one is contact model,the Member model should contain the member name, email, password, password confirmation etc.So now we are going to create our member model using devise.

$ rails generate devise member

This will create a model member and configure it with default Devise modules.And will also create some more files in your directory. The migration file will located in db/migrate/devise_create_members.rb.After that you should have to run db:migrate as the generator will have created a migration file.

$ rake db:migrate

== DeviseCreateMembers: migrating ============================================
-- create_table(:members)
-> 0.2575s
-- add_index(:members, :email, {:unique=>true})
-> 0.3146s
-- add_index(:members, :reset_password_token, {:unique=>true})
-> 0.4259s
== DeviseCreateMembers: migrated (0.9986s) ===================================

Once you run the db:migrate command,rails will create a table called members with the following field that the Devise specified in the migration file.Check the tables has created successfully.

Now we have successfully generated our model.Just run the server by typing “rails server”.

$ rails server

=> Booting WEBrick
=> Rails 3.1.3 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-01-01 16:40:49] INFO WEBrick 1.3.1
[2012-01-01 16:40:49] INFO ruby 1.9.2 (2011-07-09) [i686-linux]
[2012-01-01 16:40:49] INFO WEBrick::HTTPServer#start: pid=5268 port=3000

copy and past the address http://0.0.0.0:3000/ to your browser search bar,you can see the rails home page .then you also try the following one. The Devise’s magic is comes here.

http://0.0.0.0:3000/members/sign_up

http://0.0.0.0:3000/members/sign_in

Here you could see that devise has generated the sign-up and sign-in forms for you.

Here the sign-up form contains only 3 fields email,password & password confirmation,No we have to add the username to the sign-up form.

run the following command to add the username field to members migration.

rails generate migration add_username_to_members username:string

This command will generate another migration file in your “db/migrate” directory.

And then again you have to run the “db:migrate” command.Then only the field will add to the members table.

$ rake db:migrate

== AddUsernameTomembers: migrating =======================================
-- add_column(:members, :username, :string)
-> 0.3149s
== AddUsernameTomembers: migrated (0.3151s) ==============================

Now you check the members table,username field will be added to it.

Creating Views :

Once you have done this you have to generate the Devise views,then only we can edit the sign-up form and add the username field to the form.

$ rails generate devise:views

Once you run this command the devise will generate the whole view files for the members.check “app/views/devise” ,you could see the whole form structure for sign-in,sign-up,forgot password etc.

Then edit the form for sign-up and add the username field to it.Go to “app/views/devise/registration/new.html.erb” and then edit the form like given below.

<h2>Sign up</h2>

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>

<div><%= f.label :username %><br />
<%= f.text_field :username %></div>

<div><%= f.label :email %><br />
<%= f.email_field :email %></div>

<div><%= f.label :password %><br />
<%= f.password_field :password %></div>

<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>

<div><%= f.submit "Sign up" %></div>
<% end %>

<%= render :partial => "devise/shared/links" %>

Now check the sign-up form again you can see the username field in it.

Lets create our second model Contact.Here we doesn’t use devise generator ,in contact model we need only 2 fields, phone number, address.

$ rails generate model contact

Edit the migration file of contact and specify the 2 fields as shown below.

class CreateContacts < ActiveRecord::Migration
def up
create_table :contacts do |t|

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

end

end

def down
drop_table :contacts

end
end

After that run db:migrate command to create a table contacts in our database.

$ rake db:migrate

== CreateContacts: migrating =================================================

-- create_table(:contacts)
-> 0.2141s
== CreateContacts: migrated (0.2142s) ========================================

Creating Controller :

We haven’t created an home page yet,so now we are going to create a controller for that.

$ rails generate controller home

And then create a new index file for home controller like “app/views/home/index.html.erb” and then add the following .

<% if member_signed_in? %>

<h3>you have succesfully signed in</h3>
<%= link_to "Sign Out", destroy_member_session_path, :method => :delete %>

<% else %>

<h1> welcom to rails community</h1>
<%= link_to "Sign In", new_member_session_path, :method => :get %>
<%= link_to "Sign up", new_member_registration_path, :method => :get %>

<% end %>

Once you have done ,you have to remove the index page in public folder,and then you should have to reset the root path to “home#index” page.

app/config/routes.rb

add the line

root :to =>'home#index'

Now we have to override the devise controller ,then only we can call the objects from 2 models (contact,members),so now we are going to create a new controller called “registration”.

$ rails generate controller registration

Open the controller file in “app/controllers/registration_controller.rb”,and then edit the file as shown below.

Filepath : app/controllers/registration_controller.rb

class RegistrationController < Devise::RegistrationsController

def new

@member= Member.new
@contact = Contact.new
end

def create

@member = Member.new
@member.username = params[:member][:username]
@member.email = params[:member][:email]
@member.password = params[:member][:password]
@member.password_confirmation =params[:member][:password_confirmation]

@contact = Contact.new
@contact.mobile = params[:contact][:mobile]
@contact.address = params[:contact][:address]
@member.valid?
if @member.errors.blank?

@member.save
@contact.member = @member
@contact.save
redirect_to dashboard_path
else
render :action => "new"
end
end

end

Once you have done the above step,we are going to create a view for our registration controller, create file called “new.html.erb”,in your “app/views/registration/” directory and then add the following.

Filepath : app/views/registration/new.html.erb

<h2>Sign up</h2>

<%= form_tag(member_registration_path,:method => 'post') %>
<%= devise_error_messages! %>
<table>

<tr>
<td>Username : </td>
<td><%=text_field_tag "member[username]",@member.username %></td>
</tr>

<tr>
<td>Email : </td>
<td><%=email_field_tag "member[email]",@member.email %></td>
</tr>

<tr>
<td>Password : </td>
<td><%=password_field_tag "member[password]",@member.password %></td>
</tr>

<tr>
<td>Retype password : </td>
<td><%=password_field_tag "member[password_confirmation]",@member.password_confirmation %></td>
</tr>

<tr>
<td>Mobile : </td>
<td><%=text_field_tag "contact[mobile]" ,@contact.mobile %></td>
</tr>

<tr>
<td>Address : </td>
<td><%=text_area_tag "contact[address]" ,@contact.address ,:rows => 10, :cols => 25 %></td>
</tr>

<tr>
<td><%= submit_tag nil, :class => "form_submit"%></td>
</tr>
</table>
<br />
<%= render :partial => "devise/shared/links" %>

We have to mention the relationships between 2 models (member ,contact ).here the relationship will be as follows.

Filepath : app/models/member.rb

class Member < ActiveRecord::Base

devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

attr_accessible :email, :password, :password_confirmation, :remember_me, :username
has_one :contact
end

Filepath : app/models/contact.rb

class Contact < ActiveRecord::Base
belongs_to :member
end

Now refer the registration controller file in app/controllers/registration,here after completing the registration & the values that the member entered is stored in the table successfully ,i just redirected the member to the dashboard page.So we have to add that page to our home controller.

Filepath : app/views/home/dashboard.html.erb

<p>hi welcome to Ruby community. you have successfully registered to your rails club account</p>
<%= link_to "Sign out", destroy_member_session_path, :method => :delete %>

You have to specify this path in our routes.rb file

Filepath : app/config/routes.rb

devise_for :members,:controllers => { :registrations =>'registration'}
match 'dashboard' => 'home#dashboard'

Conclusion :

Finally  the application has almost done,so run the server and try our application in your machine whether everything working perfectly or not.This is just a skeleton of our application,we can add a lot more css to design our application to make everything looks perfect.

I hope that this tutorial will help you to start experiencing on Ruby on Rails application.If you facing any problems when you start trying out this application on your working environment,feel free to shoot your questions or suggestions. If you wants to get the fullcode of this application,please refer.

https://github.com/sreeharikmarar/simple-application-in-rails-using-devise

I have also uploaded this application in Heroku.Check out the following link.

http://railscommunity.herokuapp.com/

This entry was posted in Uncategorized. Bookmark the permalink.

18 Responses to Creating a simple Ruby on Rails application using Devise

  1. I followed your tutorial and it was great!

    I was wondering if you can help me:
    How would I make it so once the user successfully logs in, he is redirected to a new simple page (separate from the home page) that says Welcome to your account! I created a new home page so it’s awkward when he simply returns back to that home page again once he’s logged in (by the if, else rule).
    I tried creating a new controller for user, but I’m not sure how to redirect him to user/index.html once he is logged in. I’d imagine that its related to routes.rb but if you can help me, that would be great.

    Thanks!

    • Hi Rey Lee ,

      You can put the following code in your Application Controller for redirecting a user after signed in.

      def after_sign_in_path_for(resource)
      sign_in_url = “your new controller action path ”
      end

  2. This is amazing! Thank you very much. After 2 days of googling I finally found what to do with devise.

  3. Edgar says:

    Hi Sreeharikmarar,
    I am following your tutorial and I am stuck currently in the part “Edit the migration file of contact and specify the 2 fields as shown below.” I modified the file and when I try to run “rake db:migrate” I get the error: undefined method `database_authenticatable’
    Can you help me? I have gem devise (3.0.0)
    Thank you in advance

    • Edgar says:

      Hi, I managed to get through by modifying the migrate/create_contacts.rb
      I changed the t.database_authenticatable :null => false for:
      ## Database authenticatable
      t.string :email, :null => false, :default => “”
      t.string :encrypted_password, :null => false, :default => “”

      However, now I am stuck in app/views/registration/new.html.erb with the following error:
      Showing C:/java/Aptana Studio 3 Workspace/mlarchiv/app/views/registration/new.html.erb where line #5 raised:
      undefined local variable or method `resource’ for #<#:0x60b3aa>

      Sorry but I am new with Ruby therefore I’m struggling so much getting this running

  4. Daniel Ground says:

    Really great post! thank you. Very useful.
    Greetings from Uruguay

  5. faisal says:

    i follow your instruction but i get error in rake db:migrate for contacts.
    it shows like below

    rake aborted!
    An error has occurred, this and all later migrations canceled:

    undefined method `database_authenticatable’ for #C:/Sites/rails-club/db/migrate/20130922154211_crea
    te_contacts.rb:4:in `block in up’
    C:/Sites/rails-club/db/migrate/20130922154211_create_contacts.rb:3:in `up’
    C:in `migrate’
    Tasks: TOP => db:migrate
    (See full trace by running task with –trace)

    any clue?

  6. A small error – In routes.rb instead of
    devise_for :members,:controllers => { :registrations =>’registration’}
    it should be
    devise_for :members,:controllers => { :registration =>’registration’}
    as the controller name was registration and not registrations.
    And thanks a lot for this wonderful tutorial.

  7. Khalil Bezzine says:

    Thank you for this good tutorial.

    Using rails 4.0.0 and Ruby 2.0 the ligne “t.database_authenticatable :null => false” in the file /db/migrate/create_contacts.rb” should be updated to “t.string :mobile, :null => false, :default => “”” …

    Good luck 🙂

  8. Hi,
    Great work.
    This part got updated right?

    Edit the migration file of contact and specify the 2 fields as shown below.

    class CreateContacts false

    t.string :mobile
    t.string :address

    end

    end

    def down
    drop_table :contacts

    end
    end

    tooooooooo

    class CreateContacts false

    t.string :mobile, :null => false, :default => “”
    t.string :address, :null => false, :default => “”
    end
    end

    def down
    drop_table :contacts
    end

    end

    correct it if not.

  9. Hi,
    one more correction, In order to have relationship between member and contact table, member_id column have to be added in contact table so have to run this command

    rails g migration add_member_id_to_contact member_id:integer

    after

    rake db:migrate

    Then sing_up into application.

    In rails c check relation by

    a=Member.last

    o/p:

    #
    1.9.3-p429

    Contact.last

    o/p:
    #

    a.contact

    #

    thats it………..

  10. Hi,
    one more correction, In order to have relationship between member and contact table, member_id column have to be added in contact table so have to run this command

    rails g migration add_member_id_to_contact member_id:integer

    after

    rake db:migrate

    Then sing_up into application.

    In rails c check relation by

    a=Member.last

    o/p:

    Member id: 3, email: “a@gmail.com”, encrypted_password: “$2a$10$WastWB8Y7Li.IDt3DPGdweRGCDR4tX99pyreghRM.4dc…”, reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: “2013-10-18 11:56:51”, updated_at: “2013-10-18 11:56:51”, username: “a”

    Contact.last

    o/p:

    Contact id: 2, mobile: “123456789s”, address: “testssax”, member_id: 3

    a.contact

    Contact id: 2, mobile: “123456789s”, address: “testssax”, member_id: 3

    thats it………..

  11. Craig says:

    Why is this on wordpress?

  12. dario says:

    this is a very good tutorial!
    thanks! 🙂

Leave a reply to praaveen Ranganathan Cancel reply