Ruby on Rails Authentication and Authorisation Tutorial

Ruby on Rails Authentication and Authorisation with EMail confirmation user activation.

What you will learn here:

  • How to create authentication and authorisation in Ruby on Rails.
  • Furthermore, when a user signs up he is sent an email to which he must respond to activate his account.
  • The IP address from which the user signs up is recorded. By default his creation date is also recorded.
  • Use a globally unique ID for users, not the default integers starting at 1. I did this because the verification link in the email contains the user id. A mischievous user can reconstruct the link with a user id smaller than his, if the default integers were used, to see what mischief he can practise. Also, of course, when it comes to users/show it's easy to use integers to page through the users. A GUID does not allow either of these two scenarios.

Install Ruby and Rails

To start off with, install Ruby and Rails if you don't already have them.
I'm assuming you're on Linux. If you're on Windows, why? So go to Download Ruby Page and follow the instructions to install Ruby. To make this generic over all distributions, I'll go with the compile and install from code instructions. Wherever you see $ sudo, if you don't know what that means, sign in as superuser root and do whatever sudo is supposed to do.

Make sure you have the necessary prerequisites. If you're on Debian or one of its children (Ubuntu, Mepis, etc.) do
$ sudo apt-get install build-essential libssl-dev libreadline5-dev zlib1g-dev
If not, download the libraries indicated above. The build-essential package is a list of what Debian needs to build from code. It consists of 23 packages like, bash, tar, etc. on my computer. You will need something like gcc to compile with. Use
$ gcc -v
to see if you have it. On my machine version 4.3.2 is installed.

This will get you the latest stable Ruby package:
$ wget
Now follow the instructions on the download Ruby page. I'll repeat them here for completeness sake.

First, $ tar xzf stable-snapshot.tar.gz
Then $ cd ruby/
$ ./configure
$ make
$ sudo make install

Now see what was installed.
$ ruby -v
On my machine I get ruby 1.8.8dev (2009-06-19) [x86_64-linux]

If you have installed ruby 1.9.1 or above, you apparently don't need Ruby Gems, as it comes with the Ruby installation. However, if you need Ruby Gems, go to Ruby Gems and download the latest Ruby Gems. Note this is not the link or version of Ruby Gems on the Ruby on Rails Wiki page. Now do the following:
$ tar xzvf rubygems-1.x.x.tgz (mine was 1.3.4)
$ cd rubygems-1.x.x
$ sudo ruby setup.rb

The Wiki page talks of creating symbolic links in /usr/bin. On my system (Debian Lenny) everything was installed in /usr/local and executables, not links, placed in /usr/local/bin. You may want to have a look and see where everything is installed and create symbolic links as explained on the Wiki page, if needed.

Now install Rails:
$ sudo gem install rails
To see which rails was installed, do
$ rails -v
I get Rails 2.3.2

The Database and its Ruby Connector

You will need a database to follow along. Install either MySQL or PostgreSQL using your distribution package installer. Then set up your database so you can log into it and create databases, tables, populate the tables, etc. What this means is that you should create users (at least one) in your database and give him certain permissions. If you don't know how to do this, go to the website of the database you installed and follow the instructions. See that you install the package that connects your database to Ruby:
$ sudo gem install mysql I installed postgresql here.
Have a look at your database.yml file once it is generated. It is here that you specify the details of the database the application has to connect to. We will get there very soon.

The Application

We will need the following functionality:

  1. Create a new user
  2. Send e-mail to the new user
  3. New user uses the e-mail to activate his account or delete himself from the database
  4. New user can now log in
  5. Once logged in the new user can change his password
  6. User can log out
  7. User can request a new password be sent to him using his e-mail address

For all the above we will need the following forms:

  1. A sign up form
  2. A log in form
  3. A change password form
  4. A form to request a new password

Logging out will just be an action link.

To start your application, open a terminal window (Windows users, a command window) and migrate to where you want to build this project. Say /home/yourname/projects/ruby. Now enter
$ rails authenticate -d postgresql
If you are going to use Mysql enter mysql rather than postgresql. Things will scroll by on the term window and you will end up with a directory structure like this:
rails generated directory structure of a rails project

Now create your databases. For me it was:
$ createdb authenticate_development
$ createdb authenticate_production
$ createdb authenticate_test
Of course, if you don't use PostgreSQL or used a different project name, things will be different.

Now open authenticate/config/database.yml in a text editor. This is what my database.yml looks like. Fill in the user name and password in the relevant places. You will see provision is made to connect to the database using TCP/IP. Apparently this is a must in Windows. If you're on Windows, uncomment those lines.

Your model

Model is just what a class representing a database table is called. In Ruby there is no mapping between the class and the database table, like in Java where every column in the table is represented by a member of the class. Also, in Ruby the model class can contain methods used to do things on one row in the table - in this case a certain user. These things can be logging in this certain user, changing his password, etc. In Java these methods will be in a different class, an action class or session bean. Our model here is going to be the class User.rb which will be represented by a table called users.

You may remember that our users are not going to have the default integer ID generated by Rails. So, let's install the GUID plugin which will generate 22 char guids for our user primary keys. Download and unzip into authenticate/vendor/plugins/guid/ Inside guid you should have an init.rb and README.TXT files and a lib directory.

Now a short detour; the GUID plugin uses the computer's mac address, obtained by calling /sbin/ifconfig, to generate the guid. On one of the commercial hosts, Dreamhost, one is not allowed to call /sbin/ifconfig and key generation fails. The fix is simple: migrate into the authenticate/vendor/plugins/guid/lib directory and open uuidtools.rb in a text editor. Near the top (line 106 for me) you will find @@mac_address = nil. Change that to @@mac_address = "12:23:23:45:78:34" or something similar in that format. You can obtain your computer's mac address by calling /sbin/ifconfig and use that. Of course, if you don't have the problem calling /sbin/ifconfig you don't have to do any of this.

Now, let's create our model:

$ cd authenticate  #All the commands are going to be issued from this directory, from now on.
$ ruby script/generate model user login:string clearance:integer name:string surname:string email:string ip_address:string salt:string hashed_password:string activated:boolean
exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/user.rb
create  test/unit/user_test.rb
create  test/fixtures/users.yml
create  db/migrate
create  db/migrate/20090707125413_create_users.rb

Open authenticate/db/migrate/date_create_users.rb in a text editor. First of all (1) we have to tell Rake not to create the default, auto incrementing, integer ID primary key. Then (2) we have to tell it to create an ID column of data type varchar(22). Next (3) we have to tell it to set this column as the primary key. The areas to change the generated file are all marked in the code below.

class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users, :id => false do |t| 		(1)
t.string :id, :limit => 22			  		(2)
t.string :login, :limit => 15
t.integer :clearance
t.string :name
t.string :surname
t.string :email
t.string :ip_address
t.string :salt
t.string :hashed_password
t.boolean :activated

execute "ALTER TABLE users ADD PRIMARY KEY (id)"	(3)

def self.down
drop_table :users

Now we're going to create our table:

$ rake db:migrate
(in /home/chris/projects/ruby/authenticate)
==  CreateUsers: migrating ====================================================
-- create_table(:users, {:id=>false})
-> 0.0048s
-- execute("ALTER TABLE users ADD PRIMARY KEY (id)")
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "users_pkey" for table "users"
-> 0.0283s
==  CreateUsers: migrated (0.0334s) ===========================================

If you are not using PostgreSQL, your output may not look exactly the same and you will need to log into your database in a different way.

Let's see what happened in the database and which tables were generated and how they look:

$ psql authenticate_development
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

authenticate_development=# \dt
public | schema_migrations | table | chris
public | users			 | table | chris
We see two tables both belonging to me. We are interested in users.
authenticate_development=# \d users
id			  | character varying(22)	   | not null
login		   | character varying(15)	   |
clearance	   | integer					 |
name			| character varying(255)	  |
surname		 | character varying(255)	  |
email		   | character varying(255)	  |
ip_address	  | character varying(255)	  |
salt			| character varying(255)	  |
hashed_password | character varying(255)	  |
activated	   | boolean					 |
created_at	  | timestamp without time zone |
updated_at	  | timestamp without time zone |

This is about what we wanted. You can now log out of your database.

We want to check that the e-mail address the user enters confirms to the format of an e-mail address. Get rfc822.rb and copy and paste that to a file with the same name in your project's lib directory. Personally, I would also like the people signing up not to use a web mail host, like hotmail, gmail, etc. Anyone can create an account like that and use it to activate his account with your site. Therefore, I created a small ruby file, consisting of one method,to weed out some of the more common web mail hosts. Open web_mail_hosts.rb and copy and paste, or right click and save it to a file with the same name in your project's lib directory.

You remember I said the model class will do some work on itself. Below is what the code should look like. First of all we tell it to use the plugin to create globally unique indentifiers and the rfc822 class to check the format of e-mail addresses.

class User < ActiveRecord::Base
include RFC822

validates_length_of :login, :within => 5..40
validates_length_of :password, :within => 5..40
validates_presence_of :login, :email, :password, :password_confirmation, :name, :surname
validates_uniqueness_of :login, :email
validates_confirmation_of :password
validates_format_of :email, :with => EmailAddress

attr_protected :id, :salt

attr_accessor :password, :password_confirmation

def self.authenticate(login, pass)
u=find(:first, :conditions=>["login = ?", login])
return nil if u.nil?
return u if User.encrypt(pass, u.salt)==u.hashed_password

def password=(pass)
self.salt = User.random_string(10) if !self.salt?
self.hashed_password = User.encrypt(@password, self.salt)

def send_new_password
new_pass = User.random_string(10)
self.password = self.password_confirmation = new_pass
Notifications.deliver_forgot_password(, self.login, new_pass)

def send_activate
Notifications.deliver_activate(,, self.surname,

def activate?
update_attribute('activated', true)
if self.activated
  return true
  return false


def self.encrypt(pass, salt)

def self.random_string(len)
#generat a random password consisting of strings and digits
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
return newpass

You will see that this class contains methods to authenticate itself, set a password, send a new password to the user, activate itself, encrypt its password, etc.

Your controllers

chris@oberon:~/projects/ruby/authenticate$ ruby script/generate controller users new delete activate new_password forgot_password
exists  app/controllers/
exists  app/helpers/
create  app/views/users
exists  test/functional/
create  test/unit/helpers/
create  app/controllers/users_controller.rb
create  test/functional/users_controller_test.rb
create  app/helpers/users_helper.rb
create  test/unit/helpers/users_helper_test.rb
create  app/views/users/new.html.erb
create  app/views/users/delete.html.erb
create  app/views/users/activate.html.erb
create  app/views/users/new_password.html.erb
create  app/views/users/forgot_password.html.erb

As you can see, the above created a controller, users_controller.rb of the class UsersController, in the app/controllers directory. This controller has the five methods, new, delete, activate, new_password and forgot_password which we specified when creating this controller. We also have a view for each of the five methods in app/views/users.

Let's also create a controller to handle logins.

chris@oberon:~/projects/ruby/authenticate$ ruby script/generate controller logins login logout logged_in logged_out
exists  app/controllers/
exists  app/helpers/
exists  app/views/logins
exists  test/functional/
exists  test/unit/helpers/
create  app/controllers/logins_controller.rb
create  test/functional/logins_controller_test.rb
create  app/helpers/logins_helper.rb
create  test/unit/helpers/logins_helper_test.rb
create  app/views/logins/login.html.erb
create  app/views/logins/logout.html.erb
create  app/views/logins/logged_in.html.erb
create  app/views/logins/logged_out.html.erb

In this controller we are just interested in logging in and logging out. The logged_in and logged_out methods are going to be empty. We are just interested in their views for the sake of this tutorial.

You will also find a controller, application_controller.rb, with the two controllers we just created. Rails did this when we created the project. Code in application_controller.rb is accessible from any controller, and if we indicate a method is a helper_method it is also accessible from any view. We will be coming back to this shortly.

OK, so what's first? When we land on this site, we want to be able to sign up. That's to say, create a new user. So, let's go to the user controller. First of all, we set up a filter, which is not written yet, to require that a user be logged in before he can change his password. Then we "import" the web_mail_hosts.rb file which lives in authenticate/lib. Then we create the new method. This is what it looks like:

class UsersController < ApplicationController
before_filter :login_required, :only=> [:new_password, :delete]
require 'web_mail_hosts'

def new
	@user =[:user])
	@user.clearance = 0;
	if not_wanted?(  # user submitted an email address from a web mail host
		flash[:warning] = "Your email address appears to be web based"
		render  :action => 'new'
		flash[:notice] = "Signup successful. Activation e-mail has been sent"
		redirect_to  :controller => 'logins', :action => 'login'
		flash[:warning] = "Please try again - problems saving your details to the database"
		render :action => 'new'

def delete

def activate

def new_password

def forgot_password



The test for form data submission (if is done so that if this method is called in any way but from a form, only its view will be displayed without executing any of its code.

We have called at least two methods, ip_address and clearance that are not implemented yet. We may want to call these methods, as well as some others, from more than one controller and maybe even from some views. So we will implement them in the already mentioned application_controller.rb. This is what that class looks like:

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time

before_filter :fetch_logged_in_user

protect_from_forgery # See ActionController::RequestForgeryProtection for details

def fetch_logged_in_user
  return unless session[:user_id]
  @current_user = User.find_by_id(session[:user_id])

def logged_in?
! @current_user.nil?
helper_method :logged_in?

def clearance
if logged_in?
  return @current_user.clearance
  return nil
helper_method :clearance

def login_required
return true if logged_in?
session[:return_to] = request.request_uri
flash[:notice]="You have to log in!"
redirect_to :controller => 'logins', :action => 'login' and return false

def ip_address
return request.remote_ip

# Scrub sensitive parameters from your log
# filter_parameter_logging :password

Your views

Or rather, your views this far. To start off with, we will need the main layout view that all other views are going to use as a template, application.html.erb. This file is in authenticate/app/view/layouts. This is what it should look like:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">
<html xmlns="" xml:lang="en" lang="en">
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Authenticate Application</title>
<%= stylesheet_link_tag 'black' %>
<%= javascript_include_tag :defaults %>

<div id="shell">
<div id="toplinks">
<% if !logged_in? %>
	  <%= link_to 'Sign Up', '/users/new' %>
<% end %>
<% if logged_in? %>
	  <%= link_to 'Change Password', '/users/change_password' %>
<% end %>
<div id="login_logout">
	<% if @current_user %>
		Logged in as: <%= @current_user.login %>
		<em><%= link_to "(Logout)", '/logins/logout' %></em>
	<% else %>
		<em>Not logged in.</em>
		<%= link_to 'Login', '/logins/login' %>
	<% end %>
<div class="clear"></div>
<% unless flash[:notice].blank? %>
<div id="notification"><%= flash[:notice] %></div>
<% end %>
<% unless flash[:warning].blank? %>
<div id="warning"><%= flash[:warning] %></div>
<% end %>
<%= yield %>

You can download the stylesheet, which must be saved in authenticate/public/stylesheets, here and the navigation division background image, which must be saved in authenticate/public/images, here.

The next file is authenticate/app/views/users/new.html.erb. It should look like this:

<% if !logged_in? %>
<h2>Sign up</h2>
<%= error_messages_for 'user' %>
<p>Please fill in all fields</p>
<p>Your user name and password must be between 5 and 40 alphanumeric characters.</p>
<p>Please do not submit web mail addresses, like <b>hotmail, gmail</b> and others. Use your e-mail address with your ISP.</p>
<p><strong>Your email address must be valid.</strong> We will send you an email which you must use to activate your account.
You will not be able to log in or upload announcements until your account is activated.</p>
<% form_for(:user, @user, :url => {:action=> 'new'}) do |f| %>
<legend>New User Data</legend>
<label for='user_login'>Username</label><br/>
<%= f.text_field :login, :size => 40 %>
<label for='user_name'>First Name</label><br/>
<%= f.text_field :name, :size => 40 %>
<label for='user_surname'>Surname or Last Name</label><br/>
<%= f.text_field :surname, :size => 40 %>
<label for='user_password'>Password</label><br/>
<%= f.password_field :password, :size => 40 %>
<label for='user_password_confirmation'>Password Confirmation</label><br/>
<%= f.password_field :password_confirmation, :size => 40 %><br/>
<label for='user_email'>Email</label><br/>
<%= f.text_field :email,  :size => 40 %><br/>
<%= submit_tag 'Signup' %>
<% end %>
<% else %>
<h2>You are already logged in and therefore signed up</h2>
<% end %>

Now you are nearly ready to see the first fruits of your handiwork. All we have to do is make sure you will be presented with the sign-up page when requesting the url. Open authenticate/config/routes.rb and under # map.root :controller => "welcome" add the line map.root :controller => "users", :action => "new" Now you will be taken to the sign up form as soon as your application opens.

In the authenticate directory type ruby script/server into a terminal window and watch the server start up. Now fire up your browser and type http://localhost:3000/ into the address field. You should be rewarded with the following gratifying sight:

sign up page

All the code to create a new user is already in place, but the code for sending an activation e-mail still needs to be done. So, let's do it.

Your mailers

You will want to send out two kinds of e-mail messages:

  • Messages asking the user who signed up to activate.
  • Messages supplying a user who lost his password with a newly generated password
So, without further ado, let's do it:
chris@oberon:~/projects/ruby/authenticate$ ruby script/generate mailer notifications forgot_password activate
exists  app/models/
create  app/views/notifications
exists  test/unit/
create  test/fixtures/notifications
create  app/models/notifications.rb
create  test/unit/notifications_test.rb
create  app/views/notifications/forgot_password.erb
create  test/fixtures/notifications/forgot_password
create  app/views/notifications/activate.erb
create  test/fixtures/notifications/activate

As you can see, in authenticate/app/models, notifications.rb was generated and in authenticate/app/views/notifications, forgot_password.erb and activate.erb were generated. These two views are templates of the e-mail that your mailer, notifications.rb is going to use. Note the .erb extension of these templates as opposed the .html.erb extensions of the other views.

Without going into too much detail, this is what activate.erb looks like:

<title>Mail from Authenticate</title>
<table style="width: 555px; margin: 10px auto; border: 1px black solid;">
<tr><td style="background: #dfdfdf; text-align: center;"><h2 style="margin: 8px auto 8px auto;">Activate Your Authenticate Account</h2></td></tr>
<td style="text-align: left; padding: 5px 10px;">
  <p>Welcome to <strong>Authenticate</strong>, <strong><%= @name %> <%= @surname %></strong></p>
  <p><strong>Authenticate</strong> received a sign-up request using <%= @email %>.  If it is indeed from you
  and you wish to activate your account, click <a href="http://localhost:3000/users/activate?id=<%= @id %>">here.</a></p>
  <p>Should you wish to be completely removed from our database, click
  <a href="http://localhost:3000/users/delete?id=<%= @id %>">here.</a></p>

You will notice that this is a simple html layout for an e-mail. Everyting is in the code, no images or style sheets to be downloaded from elsewhere. For e-mails a simple table layout is best.

And this is what forgot_password.erb looks like:

<title>Mail from Authenticate</title>
<table style="width: 555px; margin: 10px auto; border: 1px black solid;">
<tr><td style="background: #dfdfdf; text-align: center;"><h2 style="margin: 8px auto 8px auto;">Your Lost Password</h2></td></tr>
<td style="text-align: left; padding: 5px 10px;">
  <p><strong>Authenticate</strong> received a request for a password replacement from your e-mail address.  As your password is stored in a
  hashed format in our database, we cannot tell you what your password was.  We have generated a new, random password for you.  Please note
  that it is case sensitive.</p>
  <p>Your username is <em><%= @login %></em>. Your new password is <em><%= @pass %></em>. Please login and change it to something more memorable.</p>
  <p><a href="http://localhost:3000/logins/login">Click Here to Log In</a>
Much the same goes for forgot_password.erb as for activate.erb.

app/models/notifications.rb looks like this:

class Notifications < ActionMailer::Base

def forgot_password(to, login, pass, sent_at =
@subject	= "Your lost password"
@recipients = to
@from = ''
@sent_on = sent_at
@content_type = "text/html"

def activate(to, name, surname, id, sent_at =
@subject	= 'Account activation at Authenticate'
@recipients = to
@from = ''
@sent_on = sent_at
@content_type = "text/html"

It is clear that things like @body['login'] get tranferred to the templates, in this case to <%= @login %>.

Configuring your SMTP server

I have Exim installed on my Debian box. My ISP would not allow me to send mail using another SMTP server, but theirs. Also, all mail going out through them must have their domain and the From: field. Therefore my From address must be my email address with them. That would of course prevent me from sending 2 million spam messages apparently originating from elsewhere through their network. So I set up Exim to use a smart host SMTP server for messages going out of the local network. This smart SMTP server is of course my ISP's SMTP server. I fed its details into Exim and use Exim as if it is the SMTP server. You can try and use the SMTP server of your ISP directly. In that case type in or whatever is the address of your ISP's SMTP server where you see localhost in the example.

Here is what the end of my authenticate/config/environment.rb file looks like:

# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
# config.i18n.default_locale = :de
#ActionMailer settings
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address			=> 'localhost',
:port			=> 25,
:domain			=> ''
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.default_charset = 'utf-8'


Fire up your server by typing ruby script/server into your term window, open your browser and go to http://localhost:3000. You will see the sign up form. Fill it in and click the button. You should see the following:
signed up message

If sending the e-mail worked, you should find an e-mail looking like this in your inbox:

activation e-mail

However, before you can click any of the links we have to implement the methods in your controller handling those links. So, let's go to authenticate/apps/controllers/users_controller.rb and complete the four remaining methods. This is what they should look like:

def delete
if request.get?
	if u == nil
		flash[:warning] = "You must be logged in to delete yourself"
		redirect_to :controller => 'logins', :action => 'login'
		session[:user_id] = nil #log out
		flash[:notice] = "You were deleted from the database and logged out"
		redirect_to :controller => 'logins', :action => 'logged_out'

def activate
if request.get?
	puts + ' ' + user.surname
	if user.activate?
		flash[:notice]="You have been activated and can now log in"
		redirect_to :controller => 'logins', :action => 'login'
		flash[:warning]="We could not activate you.  Send us email."
		redirect_to :controller => 'logins', :action => 'login'

def new_password
	if @user.update_attributes(:password=>params[:password], :password_confirmation => params[:password_confirmation])
		flash[:notice]="Password Changed"
		redirect_to :controller => 'logins', :action => 'logged_in'

def forgot_password
	u= User.find_by_email(params[:email])
	if u
		if u.send_new_password
			flash[:notice]  = "A new password has been sent by email."
			redirect_to  :controller => 'logins',:action => 'login'
			flash[:warning]  = "EMail address OK, but couldn't send password"
			render :action => 'forgot_password'
		flash[:warning] = "No such email address on record"
		render :action => 'forgot_password'

If you now click on the link to activate you in your e-mail, you will be rewarded with the following page in your browser:

activated page

Login functionality

It is very obvious that we haven't done the login page yet. Go to authenticate/app/views/logins/login.html.erb and complete it to look like:

<% form_tag '/logins/login' do %>
<legend>Please log in</legend>
<label>Username:</label><br />
<%= text_field_tag :login %>
<label>Password:</label><br />
<%= password_field_tag :password %>
<p><%= submit_tag 'login' %></p>
<% end %>
<br />

   <%= link_to 'I forgot my password', :controller => 'users', :action => 'forgot_password' %><br /><br />

If you now refresh the page you will get the real login page:

login page

All that remains is your logins_controller.rb It should look like below:

class LoginsController < ApplicationController

def new

def login
	@current_user = User.authenticate(params[:login], params[:password])
	if @current_user
		if @current_user.activated
			session[:user_id] =
			flash[:notice]  = "Login successful"
			if session[:return_to]
				redirect_to session[:return_to]
				session[:return_to] = nil
				redirect_to :action => 'logged_in'
			flash[:warning]="Your account is not activated"
			render :action => 'login'
		flash[:warning] = "No such user"
		render :action => 'login'

def logout
	@current_user = session[:user_id] = nil
	flash[:notice] = 'Logged out'
	redirect_to :action => 'logged_out'

def logged_in

def logged_out


If you know fill in your user name and password and click the login button you will be logged in:

logged in page

Clicking the logout link will now log you out.

The remaining methods are now just more of the same. Changing your password or deleteting yourself once logged in is covered in the code. Similarly, requesting that a new password be mailed to you is very similar to signing up. There are a few views you don't have the code for, but they are all included in the code which you can download.

If you find what you learned on this page useful, please use the social media widgets at the bottom and pin, tweet, plus-one or whatever this page.

The functionality you have learned here is very useful. This is it. Write a note to let us know what you think of all this.

Use and empty line to separate paragraphs in the "Comment" text area.

Links and html markup are not allowed.

Submit a Comment

Great blog here! Also your site loads up fast! What web host are you using? Can I get your affiliate link to your host? I wish my website loaded up as quickly as yours lol

Unquestionably consider that that you said. Your favorite reason appeared to be on the net the easiest thing to bear in mind of. I say to you, I certainly get annoyed at the same time as people think about concerns that they just do not realize about. You managed to hit the nail upon the top and outlined out the entire thing with no need side effect , other folks can take a signal. Will probably be back to get more.Thanks

You are so cool! I do not think I have read through anything like that before. So good to find another person with a few original thoughts on this subject. Really..thanks for starting this up. This web site is something that's needed on the internet, someone with a bit of originality!


This site

I hardly ever look at the comments, my mistake. I'll do so more frequently in future. This site is hosted by Daily Razor. It's a Java application using JDBC and a PostgreSQL database. The Java Heap size is something like 192MB. The pages are plain with no Flash - most likely that has some influence on the loading speed. The loading speed is not always the same.

Strangley enough, these tutorial pages get more visitors than the rest of the site, which is supposed to attract potential clients. Most people visiting this site are not even from Australia. I'm glad some people find some things on this site useful. I'm more a function person than a form (appearance) person. So, if I can pass on some solid, useful facts, I'm happy.

It is truly a great and helpful piece of info. I'm glad that you simply shared this helpful information with us. Please keep us up to date like this. Thanks for sharing.

Spot on with this write-up, I actually believe that this website needs far more attention. I'll probably be returning to read more, thanks for the information!

Hi, I do think this is a great web site. I stumbledupon it ;) I'm going to return yet again since i have bookmarked it. Money and freedom is the greatest way to change, may you be rich and continue to guide others.

What's up to every one, for the reason that I am actually eager of reading this website's post to be updated daily. It contains nice material.

Aw, this was an extremely good post. Spending some time and actual effort to generate a superb article… but what can I say… I procrastinate a whole lot and don't manage to get nearly anything done.



Hi, i read your blog occasionally and i own a similar one and i was just curious if you get a lot of spam feedback? If so how do you reduce it, any plugin or anything you can advise? I get so much lately it's driving me insane so any help is very much appreciated.


XRumer 16.0 + XEvil 4.0 breaking ANY hard captcha

Perfect update of captchas regignizing package "XEvil 4.0": captchas solving of Google (ReCaptcha-2 and ReCaptcha-3), Facebook, BitFinex, Bing, Hotmail, SolveMedia, Yandex, and more than 8400 another subtypes of captchas, with highest precision (80..100%) and highest speed (100 img per second). You can use XEvil 4.0 with any most popular SEO/SMM programms: iMacros, XRumer, GSA SER, ZennoPoster, Srapebox, Senuke, and more than 100 of other programms.

Interested? There are a lot of introducing videos about XEvil in YouTube.

Free XEvil Demo available.

See you later ;)


XRumer 16.0 + XEvil bypass more than 8400 type of CAPTCHAs

Revolutional update of captchas recognition software "XRumer 16.0 + XEvil 4.0": captcha solution of Google (ReCaptcha-2 and ReCaptcha-3), Facebook, BitFinex, Bing, Hotmail, SolveMedia, Yandex, and more than 8400 another types of captcha, with highest precision (80..100%) and highest speed (100 img per second). You can use XEvil 4.0 with any most popular SEO/SMM programms: iMacros, XRumer, GSA SER, ZennoPoster, Srapebox, Senuke, and more than 100 of other programms.

Interested? There are a lot of demo videos about XEvil in YouTube.

Free XEvil Demo available.

Good luck ;)

rolex uhr

rolex uhren

DKNY bietet Handtaschen, Luxus - Kleidung, Handtaschen, Geldbörsen, Uhren, Mappen der Frauen, Fantasie Schmuck, Männer s Uhren, Sonnenbrillen, alle mit dem traditionellen Stil, der diese große Marke kennzeichnet.

mobilina anpassning ab

mobilina anpassning ab

you are in reality a excellent webmaster. The web site loading speed is incredible. It seems that you're doing any distinctive trick. In addition, The contents are masterwork. you've performed a fantastic process on this matter! mobilina anpassning ab mobilina anpassning ab


vitamin -

; this

" , - , - ". , " ".....


Thank you very much for the invitation

Thank you very much for the invitation :). Best wishes. PS: How are you?


Hi! Only from 18+!

I'm not just inviting you! But it will be interesting for sure


XEvil 5.0 solving BitFinex Captcha

Absolutely NEW update of captchas breaking software "XRumer 19.0 + XEvil 5.0":

Captchas solving of Google (ReCaptcha-2 and ReCaptcha-3), Facebook, BitFinex, Bing, Hotmail, SolveMedia, Yandex, and more than 12000 another size-types of captcha, with highest precision (80..100%) and highest speed (100 img per second). You can use XEvil 5.0 with any most popular SEO/SMM software: iMacros, XRumer, SERP Parser, GSA SER, RankerX, ZennoPoster, Scrapebox, Senuke, FaucetCollector and more than 100 of other software.

Interested? There are a lot of impessive videos about XEvil in YouTube.

Free XEvil Demo available.

Good luck!


Thank you very much for the invitation

Thank you very much for the invitation :). Best wishes. PS: How are you? I am from France :)


Are you 18? Come in and don't be shy!

Hurry up to look into you will find a lot of interesting things


Hi! Only from 18+!

Here you are waiting for interesting Dating only for adults!

laktosfri mjölk diabetes

My family members always say that I am killing my time here at web, however I know I am getting experience daily by reading such good posts. laktosfri mjölk diabetes


<a>светодиодный экран оптом</a> <a>светодиодный экран для магазина</a> <a>медиафасад стоимость</a> <a>купить медиафасад</a> <a>медиафасад купить</a> <a>светодиодный экран для помещений</a> <a>медиафасад цена</a> <a>светодиодные экраны</a> <a>медиафасад</a> <a>светодиодный экран купить</a> <a>светодиодный экран для улицы</a> <a>медиафасады</a> <a>светодиодный экран для сцены</a> <a>светодиодный экран цена</a> <a>уличный экран</a> <a>дорожные табло</a>

herpes i munnen symtom

Hi it's me, I am also visiting this site daily, this website is truly pleasant and the visitors are actually sharing fastidious thoughts. herpes i munnen symtom

vitamine b12 bronnen

you're truly a good webmaster. The website loading velocity is amazing. It seems that you are doing any distinctive trick. In addition, The contents are masterpiece. you've done a excellent job on this subject! vitamine b12 bronnen

Every weekend i used to pay a quick visit this web site, because i wish for enjoyment, for the reason that this this site conations truly good funny information too. styr bГҐt korsord

This page truly has all the information I needed concerning this subject and didn't know who to ask. kettlebell 24 kg

Cool blog! Is your theme custom made or did you download it from somewhere? A design like yours with a few simple tweeks would really make my blog shine. Please let me know where you got your theme. Many thanks overgangsalder smerter i underlivet

frisör vaxholm drop in

Hi there, just became aware of your blog through Google, and found that it's truly informative. I'm going to watch out for brussels. I'll appreciate if you continue this in future. Numerous people will be benefited from your writing. Cheers! frisör vaxholm drop in

You can definitely see your expertise in the work you write. The sector hopes for more passionate writers like you who aren't afraid to mention how they believe. All the time follow your heart. android pay nfc

maskerad för vuxna

Thanks in favor of sharing such a nice opinion, post is pleasant, thats why i have read it completely maskerad för vuxna

I needed to thank you for this excellent read!! I certainly loved every bit of it. I have got you saved as a favorite to look at new things you post… eksem blГҐsor hГ¤nder

I absolutely love your blog and find almost all of your post's to be exactly what I'm looking for. Do you offer guest writers to write content for you personally? I wouldn't mind creating a post or elaborating on most of the subjects you write in relation to here. Again, awesome site! cysta pГҐ Г¤ggstock symtom

best face lotion for combination skin

Thanks for one's marvelous posting! I certainly enjoyed reading it, you could be a great author. I will remember to bookmark your blog and may come back in the foreseeable future. I want to encourage that you continue your great writing, have a nice holiday weekend! best face lotion for combination skin

Greetings from Colorado! I'm bored to death at work so I decided to check out your site on my iphone during lunch break. I love the information you present here and can't wait to take a look when I get home. I'm surprised at how fast your blog loaded on my phone .. I'm not even using WIFI, just 3G .. Anyways, fantastic blog! bromssköld bmw e46

glutenfri tortilla ica

Quality posts is the crucial to attract the viewers to pay a visit the site, that's what this web page is providing. glutenfri tortilla ica

Now I am ready to do my breakfast, afterward having my breakfast coming again to read further news. d vitamin dosering vuxna

I'm pretty pleased to find this site. I need to to thank you for your time just for this wonderful read!! I definitely loved every little bit of it and i also have you bookmarked to look at new stuff on your site. billiga sandaler skor

artros fingrar symtom

If you want to grow your knowledge only keep visiting this website and be updated with the latest news update posted here. artros fingrar symtom

For the reason that the admin of this website is working, no doubt very quickly it will be famous, due to its quality contents. svart klänning lång ärm

It's fantastic that you are getting thoughts from this post as well as from our dialogue made at this time. anna lisa herascu naken

spa marstrand koön

Hi there i am kavin, its my first occasion to commenting anywhere, when i read this paragraph i thought i could also make comment due to this brilliant paragraph. spa marstrand koön

Informative article, totally what I was looking for. bygga naglar malmö

I am sure this article has touched all the internet visitors, its really really fastidious post on building up new website. audio video lindesberg

Hi, I would like to subscribe for this weblog to take newest updates, thus where can i do it please help out. vad Г¤r ringorm

finnar pГҐ halsen orsak

I am extremely impressed with your writing skills as well as with the layout on your blog. Is this a paid theme or did you customize it yourself? Anyway keep up the nice quality writing, it is rare to see a great blog like this one these days. finnar pГҐ halsen orsak

Hello, I wish for to subscribe for this website to get newest updates, therefore where can i do it please help out. kold blond hГҐrfarve

four friends valpfoder

I know this web page presents quality dependent articles or reviews and additional material, is there any other web page which provides such data in quality? four friends valpfoder

This web site definitely has all the information and facts I wanted concerning this subject and didn't know who to ask. karbamid i locobase

I always spent my half an hour to read this website's content every day along with a mug of coffee. indian store gothenburg

mГҐltid 200 kcal

Hey There. I discovered your blog the usage of msn. That is a very smartly written article. I will be sure to bookmark it and come back to read extra of your useful information. Thank you for the post. I'll definitely comeback. mГҐltid 200 kcal

Somebody necessarily help to make seriously articles I would state. This is the first time I frequented your website page and thus far? I amazed with the analysis you made to create this particular submit incredible. Fantastic activity! varm vinterrock herr

chokladfyllning till tГҐrta

This is really attention-grabbing, You are a very professional blogger. I have joined your feed and look forward to looking for extra of your magnificent post. Additionally, I have shared your website in my social networks chokladfyllning till tГҐrta

Thanks for the auspicious writeup. It actually was once a entertainment account it. Look complex to more delivered agreeable from you! However, how could we keep up a correspondence? badkar med bubblor