Find file
Fetching contributors…
Cannot retrieve contributors at this time
819 lines (804 sloc) 57.2 KB
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Rails Tutorial for Devise with RSpec and Cucumber &#183; RailsApps</title>
<link href="https://plus.google.com/u/0/b/117374718581973393536/117374718581973393536/posts/" rel="publisher" />
<link rel="stylesheet" href="http://railsapps.github.com/css/bootstrap.css" type="text/css" charset="utf-8" />
<link rel="stylesheet" href="http://railsapps.github.com/css/screen.css" type="text/css" charset="utf-8" />
<link rel="stylesheet" href="http://railsapps.github.com/css/gollum.css" type="text/css" charset="utf-8" />
<link rel="stylesheet" href="http://railsapps.github.com/css/site.css" type="text/css" charset="utf-8" />
<link rel="stylesheet" href="http://railsapps.github.com/css/syntax.css" type="text/css" charset="utf-8" />
<script src="http://code.jquery.com/jquery-1.6.min.js" type="text/javascript"></script>
<script src="http://railsapps.github.com/javascript/jquery.text_selection-1.0.0.min.js" type="text/javascript"></script>
<script src="http://railsapps.github.com/javascript/jquery.previewable_comment_form.js" type="text/javascript"></script>
<script src="http://railsapps.github.com/javascript/jquery.tabs.js" type="text/javascript"></script>
<script src="http://railsapps.github.com/javascript/gollum.js" type="text/javascript"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-5109366-14']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a href="http://railsapps.github.com/" class="brand">RailsApps Project</a>
<ul class="pull-right nav">
<li><a href="http://blog.railsapps.org/" class="twitter">Blog</a></li>
<li><a href="http://twitter.com/rails_apps" class="twitter">Twitter</a></li>
<li><a href="https://plus.google.com/117374718581973393536" class="google">Google +</a></li>
<li><a href="https://github.com/RailsApps" class="github">GitHub Repository</a></li>
</ul>
</div>
</div>
</div>
<div class="container">
<div class="content wikistyle gollum textile">
<h1>Rails Tutorial for Devise with RSpec and Cucumber</h1>
<h4>by Daniel Kehoe</h4>
<p><em>Last updated 22 June 2012</em></p>
<p>Ruby on Rails tutorial showing how to create a Rails 3.2 application using <strong>Devise</strong> with <strong>RSpec</strong> and <strong>Cucumber</strong>.</p>
<ul>
<li>
<a href="http://github.com/plataformatec/devise">Devise</a> gives you ready-made authentication and user management.</li>
<li>
<a href="http://rspec.info/">RSpec</a> is a popular alternative to the Test::Unit testing framework.</li>
<li>
<a href="http://cukes.info/">Cucumber</a> is used for Behaviour Driven Development.</li>
</ul><p>Here’s what you can do:</p>
<ul>
<li>learn as-you-go by following the steps in this tutorial to build a starter app</li>
<li>clone the <a href="http://github.com/RailsApps/rails3-devise-rspec-cucumber/">example code from the GitHub repo</a> for a ready-to-use starter app</li>
<li>generate a customized starter app with an <a href="https://github.com/RailsApps/rails3-application-templates">application template</a>
</li>
</ul><p>Generating the application gives you many options, such as using Haml for views, additional Devise modules, and various HTML5/<span class="caps">CSS</span> front-end frameworks such as Twitter Bootstrap.</p>
<h4>RailsApps Examples and Tutorials</h4>
<p>This is one in a series of Rails example apps and tutorials from the <a href="http://railsapps.github.com/">RailsApps Project</a>. See a list of similar <a href="http://railsapps.github.com/rails-examples-tutorials.html">Rails examples, tutorials, and starter apps</a>.</p>
<p>This example application uses ActiveRecord and a SQLite database. You can use the Mongoid <span class="caps">ORM</span> with the MongoDB datastore instead, for faster development without schemas or migrations. The <a href="https://github.com/RailsApps/rails3-mongoid-devise">rails3-mongoid-devise</a> example app and tutorial shows how to set up Devise and Mongoid with RSpec and Cucumber.</p>
<h2>
<a href="http://www.twitter.com/rails_apps"><img src="http://twitter-badges.s3.amazonaws.com/t_logo-a.png" title="Follow on Twitter" alt="Follow on Twitter"></a> Follow on Twitter</h2>
<p>Follow the project on Twitter: <a href="http://twitter.com/rails_apps">rails_apps</a>. Tweet some praise if you like what you’ve found.</p>
<h2>
<img src="http://railsapps.github.com/images/rails-36x36.jpg" title="Tutorial" alt="Tutorial"> Tutorial</h2>
<p>This tutorial documents each step that you must follow to create this application. Every step is documented concisely, so a complete beginner can create this application without any additional knowledge. However, no explanation is offered for any of the steps, so if you are a beginner, you’re advised to look for an introduction to Rails elsewhere. See resources for getting started with <a href="http://railsapps.github.com/rails.html">Rails</a>.</p>
<h2>Before You Start</h2>
<p>If you follow this tutorial closely, you’ll have a working application that closely matches the example app in this GitHub repository. The example app in the <a href="http://github.com/RailsApps/rails3-devise-rspec-cucumber/">rails3-devise-rspec-cucumber</a> repository is your reference implementation. If you find problems with the app you build from this tutorial, download the example app (in Git speak, clone it) and use a file compare tool to identify differences that may be causing errors. On a Mac, <a href="http://stackoverflow.com/questions/187064/graphical-diff-for-mac-os-x">good file compare tools</a> are <a href="http://en.wikipedia.org/wiki/Apple_Developer_Tools#FileMerge">FileMerge</a>, <a href="http://sourcegear.com/diffmerge/">DiffMerge</a>, <a href="http://www.kaleidoscopeapp.com/">Kaleidoscope</a>, or Ian Baird’s <a href="http://www.changesapp.com/">Changes</a>.</p>
<p>If you clone and install the example app and find problems or wish to suggest improvements, please create a <a href="http://github.com/RailsApps/rails3-devise-rspec-cucumber/issues">GitHub issue</a>.</p>
<p>To improve this tutorial, please edit this wiki page or leave comments below.</p>
<h2>Creating the Application</h2>
<h4>Option One</h4>
<p><em>Follow this tutorial.</em></p>
<p>To create the application, you can cut and paste the code from the tutorial into your own files. It’s a bit tedious and error-prone but you’ll have a good opportunity to examine the code closely.</p>
<h4>Option Two</h4>
<p><em>Use the ready-made application template to generate the code.</em></p>
<p>You can use an application template to generate a new Rails app with code that closely matches the tutorial. You’ll find an application template for this tutorial in the <a href="https://github.com/RailsApps/rails3-application-templates">Rails Application Templates</a> repository.</p>
<p>You’ll be able to give it your own project name when you generate the app. Generating the application (described below) gives you many options, such as using Haml for views, additional Devise modules, and various HTML5/<span class="caps">CSS</span> front-end frameworks such as Twitter Bootstrap.</p>
<p>Use the command:</p>
<pre>
$ rails new rails3-devise-rspec-cucumber -m https://raw.github.com/RailsApps/rails3-application-templates/master/rails3-devise-rspec-cucumber-template.rb -T
</pre>
<p>Use the <code>-T</code> flag to skip Test::Unit files.</p>
<p>The <code>$</code> character indicates a shell prompt; don’t include it when you run the command.</p>
<p>This creates a new Rails app named <code>rails3-devise-rspec-cucumber</code> on your computer. You can use a different name if you wish.</p>
<p>The application generator template will ask you for your preferences.</p>
<p>To produce an application exactly like the tutorial, make the following selections:</p>
<ul>
<li>Would you like to use <a href="http://en.wikipedia.org/wiki/Haml">Haml</a> instead of <span class="caps">ERB</span>? <strong>no</strong>
</li>
<li>Would you like to use <a href="http://rspec.info/">RSpec</a> instead of TestUnit? <strong>yes</strong>
</li>
<li>Would you like to use <a href="https://github.com/thoughtbot/factory_girl">factory_girl</a> for test fixtures with RSpec? <strong>yes</strong>
</li>
<li>Would you like to use <a href="https://github.com/notahat/machinist">machinist</a> for test fixtures with RSpec? <strong>no</strong>
</li>
<li>Would you like to use <a href="http://cukes.info/">Cucumber</a> for your <span class="caps">BDD</span>? <strong>yes</strong>
</li>
<li>Would you like to use <a href="http://intridea.com/posts/hire-a-guard-for-your-project">Guard</a> to automate your workflow? <strong>no</strong>
</li>
<li>How will you send email? <strong>#2</strong>
<ol>
<li>
<span class="caps">SMTP</span> account</li>
<li>Gmail account</li>
<li>SendGrid account</li>
</ol>
</li>
<li>Would you like to use <a href="http://github.com/plataformatec/devise">Devise</a> for authentication?
<ol>
<li>No</li>
<li>Devise with default modules <strong>#2</strong>
</li>
<li>Devise with Confirmable module</li>
<li>Devise with Confirmable and Invitable modules</li>
</ol>
</li>
<li>Would you like to manage authorization with CanCan &amp; Rolify? <strong>no</strong>
</li>
<li>Which front-end framework would you like for HTML5 and CSS3?
<ol>
<li>None <strong>#1</strong>
</li>
<li><a href="http://foundation.zurb.com/">Zurb Foundation</a></li>
<li>
<a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a> (less)</li>
<li>
<a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a> (sass)</li>
<li><a href="http://www.getskeleton.com/">Skeleton</a></li>
<li>Normalize <span class="caps">CSS</span> for consistent styling</li>
</ol>
</li>
<li>Which form gem would you like?
<ol>
<li>None <strong>#1</strong>
</li>
<li>simple form</li>
<li>simple form (bootstrap)</li>
</ol>
</li>
<li>Would you like to use <a href="https://github.com/josevalim/rails-footnotes">rails-footnotes</a> during development? <strong>no</strong>
</li>
<li>Would you like to set a robots.txt file to ban spiders? <strong>yes</strong>
</li>
<li>Would you like to add ‘will_paginate’ for pagination? <strong>no</strong>
</li>
<li>Add ‘therubyracer’ JavaScript runtime (for Linux users without node.js)? <strong>no</strong>
</li>
</ul><p>You can choose other selections if you don’t care about matching the example application exactly.</p>
<p>You can choose the <strong>Devise with Confirmable module</strong> option if you want new users to confirm their email address before gaining access to your site. If you don’t wish to require email confirmation, choose the option <strong>Devise with default modules</strong>.</p>
<h4>Option Three</h4>
<p><em>Use the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> gem to create a reusuable application template.</em></p>
<p>This is optimal if you are creating a “starter app” based on this example app but wish to customize the code for your own preferences.</p>
<p>Each step in this tutorial has a corresponding application template recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">Rails Apps Composer</a> recipes repository. You can create your own application template using the template recipes. To do so, clone the <a href="https://github.com/RailsApps/rails_apps_composer">Rails Apps Composer</a> project, customize recipes as needed, and follow the instructions to create a reusable application template file.</p>
<h2>Assumptions</h2>
<p>Before beginning this tutorial, you need to install</p>
<ul>
<li>The Ruby language (version 1.9.3 or newer)</li>
<li>Rails 3.2</li>
</ul><p>Check that appropriate versions of Ruby and Rails are installed in your development environment:</p>
<p><code>$ ruby -v</code><br><code>$ rails -v</code></p>
<p>Be sure to read <a href="http://railsapps.github.com/installing-rails.html">Installing Rails</a> for detailed instructions and advice.</p>
<h2>Create the Rails Application</h2>
<p>Beginning here, we show how to create the application from scratch.</p>
<p>Open a terminal, navigate to a folder where you have rights to create files, and type:</p>
<p><code>$ rails new rails3-devise-rspec-cucumber -T</code></p>
<p>Use the <code>-T</code> flag to skip Test::Unit files (since you are using RSpec).</p>
<p>You may give the app a different name if you are building it for your own use. For this tutorial, we’ll assume the name is “rails3-devise-rspec-cucumber.”</p>
<p>This will create a Rails application that uses a SQLite database for data storage.</p>
<p>After you create the application, switch to its folder to continue work directly in that application:</p>
<p><code>$ cd rails3-devise-rspec-cucumber</code></p>
<h4>Edit the <span class="caps">README</span>
</h4>
<p>If you’re open sourcing the app on GitHub, please edit the <span class="caps">README</span> file to add a description of the app and your contact info. Changing the <span class="caps">README</span> is important if you’re using a clone of the example app. I’ve been mistaken (and contacted) as the author of apps that are copied from my example.</p>
<h2>Set Up Source Control (Git)</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/git.rb">git</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>If you’re creating an app for deployment into production, you’ll want to set up a source control repository at this point. If you are building a throw-away app for your own education, you may skip this step.</p>
<p><code>$ git init .</code><br><code>$ git add .</code><br><code>$ git commit -m 'Initial commit'</code></p>
<p>See detailed instructions for <a href="http://railsapps.github.com/rails-git.html">Using Git with Rails</a>.</p>
<h2>Set Up Gems</h2>
<h4>About Required Gems</h4>
<p>The application uses the following gems:</p>
<ul>
<li><a href="http://rubygems.org/gems/rails">rails</a></li>
<li><a href="http://rubygems.org/gems/rspec-rails">rspec-rails</a></li>
<li><a href="http://rubygems.org/gems/database_cleaner">database_cleaner</a></li>
<li><a href="http://rubygems.org/gems/factory_girl_rails">factory_girl_rails</a></li>
<li><a href="http://rubygems.org/gems/email_spec">email_spec</a></li>
<li><a href="http://rubygems.org/gems/cucumber-rails">cucumber-rails</a></li>
<li><a href="http://rubygems.org/gems/capybara">capybara</a></li>
<li><a href="http://rubygems.org/gems/devise">devise</a></li>
</ul><h4>Set up Your Gemfile</h4>
<p>It’s a good idea to create a new gemset using rvm, the <a href="http://rvm.beginrescueend.com/">Ruby Version Manager</a>, as described in the article <a href="http://railsapps.github.com/installing-rails.html">Installing Rails</a>.</p>
<p>See <a href="http://railsapps.github.com/rails-3-2-example-gemfile.html">Example Gemfiles for Rails 3.2</a>.</p>
<p>Open your <strong>Gemfile</strong> and replace the contents with the following:</p>
<p><strong>Gemfile</strong></p>
<pre>
source 'https://rubygems.org'
gem 'rails', '3.2.6'
gem 'sqlite3'
group :assets do
gem 'sass-rails', '~&gt; 3.2.3'
gem 'coffee-rails', '~&gt; 3.2.1'
gem 'uglifier', '&gt;= 1.0.3'
end
gem 'jquery-rails'
gem "rspec-rails", "&gt;= 2.10.1", :group =&gt; [:development, :test]
gem "factory_girl_rails", "&gt;= 3.3.0", :group =&gt; [:development, :test]
gem "email_spec", "&gt;= 1.2.1", :group =&gt; :test
gem "cucumber-rails", "&gt;= 1.3.0", :group =&gt; :test, :require =&gt; false
gem "capybara", "&gt;= 1.1.2", :group =&gt; :test
gem "database_cleaner", "&gt;= 0.7.2", :group =&gt; :test
gem "launchy", "&gt;= 2.1.0", :group =&gt; :test
gem "devise", "&gt;= 2.1.0"
</pre>
<p>Check for the <a href="http://rubygems.org/gems/rails">current version of Rails</a> and replace <code>gem 'rails', '3.2.6'</code> accordingly.</p>
<p><em>Note:</em> The RailsApps examples are generated with application templates created by the <a href="https://github.com/RailsApps/rails_apps_composer">Rails Apps Composer Gem</a>. For that reason, groups such as <code>:development</code> or <code>:test</code> are specified inline. You can reformat the Gemfiles to organize groups in an eye-pleasing block style. The functionality is the same.</p>
<h4>Install the Required Gems</h4>
<p>Install the required gems on your computer:</p>
<p><code>$ bundle install</code></p>
<p>You can check which gems are installed on your computer with:</p>
<p><code>$ gem list --local</code></p>
<p>Keep in mind that you have installed these gems locally. When you deploy the app to another server, the same gems (and versions) must be available.</p>
<h2>Configuration for Haml</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/haml.rb">haml</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>In this tutorial, we’ll use the default “<span class="caps">ERB</span>” Rails template engine. Optionally, you can use another template engine, such as Haml. See instructions for <a href="http://railsapps.github.com/rails-haml.html">adding Haml to Rails</a>.</p>
<h2>Adding RSpec for Unit Testing</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/rspec.rb">rspec</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>This tutorial shows how to set up RSpec and provides example specs for use with Devise. To learn more about using RSpec, refer to <a href="http://www.pragprog.com/titles/achbd/the-rspec-book">The RSpec Book</a>.</p>
<h4>Install RSpec and Related Gems</h4>
<p>Use the gem <a href="https://github.com/rspec/rspec-rails">rspec-rails</a> to set up the app for RSpec.</p>
<p>You should have the following gems in your <strong>Gemfile</strong>:</p>
<pre>
gem 'rspec-rails', :group =&gt; [:development, :test]
group :test do
gem 'database_cleaner'
gem 'factory_girl_rails'
gem 'email_spec'
end
</pre>
<p>The gem <code>rspec-rails</code> needs to be in the <code>:development</code> group (as well as the <code>:test</code> group) to expose generators and rake tasks during development.</p>
<p>Install the required gems on your computer:</p>
<p><code>$ bundle install</code></p>
<h4>Generate RSpec</h4>
<p>Use the rspec-rails generator to set up files needed for RSpec:</p>
<p><code>$ rails generate rspec:install</code></p>
<p>The rspec-rails generator creates the files:</p>
<ul>
<li><strong>.rspec</strong></li>
<li><strong>spec/spec_helper.rb</strong></li>
</ul><p>In you did not include the -T option when you ran rails new, you can remove the <strong>test</strong> folder (it is not needed for RSpec):</p>
<p><code>$ rm -rf test/</code></p>
<h4>Add Factory Girl for Test Objects</h4>
<p>The <a href="https://github.com/thoughtbot/factory_girl">factory_girl</a> gem is used to create default model objects for tests. For example, if a controller action requires finding a User object before displaying a “show” page, Factory Girl will create a user just for a test of the controller. You’ll need <code>gem 'factory_girl_rails', :group =&gt; :test</code> in your Gemfile.</p>
<p>You’ll need a <strong>spec/factories/users.rb</strong> file to contain the factory definitions for any default objects used for testing. You can create one like this:</p>
<p><strong>spec/factories/users.rb</strong></p>
<pre>
FactoryGirl.define do
factory :user do
name 'Test User'
email 'example@example.com'
password 'please'
password_confirmation 'please'
# required if the Devise Confirmable module is used
# confirmed_at Time.now
end
end
</pre>
<p>If you’ve chosen to create the application with the Devise Confirmable module, remove the commenting to enable <code>confirmed_at Time.now</code>.</p>
<h4>Add Devise Test Helpers</h4>
<p>Using Devise, your controllers will often include <code>before_filter :authenticate_user!</code> to limit access to signed-in users. Your tests will fail unless a default user is created and logs in before each test runs. Devise provides test helpers to make it simple to create and log in a default user.</p>
<p>Create a file <strong>spec/support/devise.rb</strong>:</p>
<p><strong>spec/support/devise.rb</strong></p>
<pre>
RSpec.configure do |config|
config.include Devise::TestHelpers, :type =&gt; :controller
end
</pre>
<p>Now you can write controller specs that set up a signed-in user before tests are run.</p>
<h4>Email Spec</h4>
<p>The email_spec gem provides a collection of RSpec matchers for testing email.</p>
<p>Modify the file <strong>spec/spec_helper.rb</strong> to enable the email_spec library:</p>
<pre>
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'email_spec'
require 'rspec/autorun'
.
.
.
RSpec.configure do |config|
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
# ## Mock Framework
.
.
.
end
</pre>
<p>Don’t copy the dots. Leave the file intact and just add the email_spec lines.</p>
<h4>Skip Unit Tests for Helpers and Views</h4>
<p>By default, using a Rails generator to create a controller will create placeholder unit tests for helpers and views.</p>
<p>We’re using Cucumber scenarios (integration tests) so unit tests of helpers and views are redundant. Tell the Rails generator to skip unit tests for helpers and views.</p>
<p>Modify the file <strong>config/application.rb</strong> to include:</p>
<pre>
# don't generate RSpec tests for views and helpers
config.generators do |g|
g.view_specs false
g.helper_specs false
end
</pre>
<h4>Run RSpec</h4>
<p>Run <code>rake -T</code> to check that rake tasks for RSpec are available.</p>
<p>Prepare the database for testing by running the commands:</p>
<pre>
$ bundle exec rake db:migrate
$ bundle exec rake db:test:prepare
</pre>
<p>This will create a <strong>db/schema.rb</strong> file so <code>rake spec</code> can run successfully.</p>
<p>You should be able to run <code>rake spec</code> to run all specs. If you haven’t written any specs, you’ll see the message “No examples matching … could be found”.</p>
<p>You can copy the files from the example <a href="https://github.com/RailsApps/rails3-devise-rspec-cucumber/tree/master/spec">spec directory</a> to use our ready-made specs.</p>
<pre>
$ cd spec
$ mkdir controllers
$ cd controllers
$ curl -o home_controller_spec.rb https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/spec/controllers/home_controller_spec.rb
$ curl -o users_controller_spec.rb https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/spec/controllers/users_controller_spec.rb
$ cd ../
$ mkdir models
$ cd models
$ curl -o user_spec.rb https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/spec/models/user_spec.rb
$ cd ../../
</pre>
<p>Our ready-made specs provide tests for a User model, User controller, and Home controller. If you run <code>rake spec</code> now, you’ll see an error such as <code>Uninitialized constant ... (NameError)</code> because you haven’t created a User model, User controller, or Home controller.</p>
<p>You’ll have to complete the tutorial before <code>rake spec</code> will run successfully.</p>
<h2>Add Cucumber for Behavior Driven Development</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/cucumber.rb">cucumber</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>It’s not necessary to add Cucumber (the example will run without it). However, it’s a recommended practice to describe application functionality as “user stories” documented as Cucumber scenarios. It’s a good way to plan development and, using Cucumber, you’ll have specifications for automated acceptance testing. To learn more about using Cucumber, refer to <a href="http://pragprog.com/book/hwcuc/the-cucumber-book">The Cucumber Book</a>.</p>
<p>This tutorial shows how to set up Cucumber with Devise.</p>
<h4>Cucumber Gems</h4>
<p>Use the gem <a href="https://github.com/aslakhellesoy/cucumber-rails">cucumber-rails</a> to set up the app for Cucumber.</p>
<p>You should have the following gems in your <strong>Gemfile</strong> file:</p>
<pre>
group :test do
gem 'cucumber-rails'
gem 'capybara'
gem 'database_cleaner'
gem "email_spec"
end
</pre>
<p>Install the required gems on your computer (if you haven’t already done so):</p>
<p><code>$ bundle install</code></p>
<p>Use the cucumber-rails generator to set up files needed for Cucumber:</p>
<p><code>$ rails generate cucumber:install --capybara --rspec</code></p>
<p>The <code>-–capybara</code> option specifies Capybara instead of the default Webrat for acceptance testing. The <code>-–rspec</code> option enables RSpec matchers for your step definitions.</p>
<p>The cucumber-rails generator creates the directories:</p>
<ul>
<li><strong>features/step_definitions</strong></li>
<li><strong>features/support</strong></li>
</ul><p>The cucumber-rails generator creates the files:</p>
<ul>
<li><strong>config/cucumber.yml</strong></li>
<li><strong>features/support/env.rb</strong></li>
<li><strong>lib/tasks/cucumber.rake</strong></li>
<li><strong>script/cucumber</strong></li>
</ul><h4>Database Cleaner for Cucumber</h4>
<p>To reset your application database to a pristine state during testing, Cucumber makes use of <a href="http://github.com/bmabey/database_cleaner">Database Cleaner</a>. The file <strong>features/support/env.rb</strong> is already set up to use Database Cleaner:</p>
<pre>
begin
DatabaseCleaner.strategy = :transaction
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
</pre>
<h4>Email Spec</h4>
<p>The email_spec gem provides a collection of Cucumber steps for testing email.</p>
<p>Add a file <strong>features/support/email_spec.rb</strong> to enable the email_spec library:</p>
<pre>
require 'email_spec/cucumber'
</pre>
<p>Create a set of Cucumber step definitions for testing email:</p>
<pre>
$ rails generate email_spec:steps
</pre>
<p>This creates a file <strong>features/step_definitions/email_steps.rb</strong>.</p>
<h4>Run Single Features Easily</h4>
<p>You can run a single Cucumber feature with a command such as:</p>
<pre>
$ bundle exec cucumber features/visitors/request_invitation.feature --require features
</pre>
<p>To save some typing, you can eliminate the need for <code>--require features</code> by changing the <strong>config/cucumber.yml</strong> file:</p>
<pre>
std_opts = "-r features/support/ -r features/step_definitions --format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
</pre>
<h4>Run Cucumber</h4>
<p>Run <code>rake -T</code> to check that rake tasks for Cucumber are available.</p>
<p>You should be able to run <code>rake cucumber</code> (or more simply, <code>cucumber</code>) to run all Cucumber scenarios and steps. If you haven’t written any Cucumber scenarios and steps, you’ll see the message “0 scenarios, 0 steps”.</p>
<p>You can copy the files from the example <a href="https://github.com/RailsApps/rails3-devise-rspec-cucumber/tree/master/features">features directory</a> to use our ready-made Cucumber feature files.</p>
<pre>
$ cd features
$ cd support
$ curl -o paths.rb https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/support/paths.rb
$ cd ../
$ cd step_definitions
$ curl -o user_steps.rb https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/step_definitions/user_steps.rb
$ cd ../
$ mkdir users
$ cd users
$ curl -o sign_in.feature https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/users/sign_in.feature
$ curl -o sign_out.feature https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/users/sign_out.feature
$ curl -o sign_up.feature https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/users/sign_up.feature
$ curl -o user_edit.feature https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/users/user_edit.feature
$ curl -o user_show.feature https://raw.github.com/RailsApps/rails3-devise-rspec-cucumber/master/features/users/user_show.feature
$ cd ../../
</pre>
<p>If you’ve chosen to create the application with the Devise Confirmable module, you should change one step in the <strong>features/step_definitions/user_steps.rb</strong> file:</p>
<pre>
Then /^I should see a successful sign up message$/ do
page.should have_content "Welcome! You have signed up successfully."
end
</pre>
<p>should be changed so all Cucumber scenarios pass when the Devise Confirmable module is used:</p>
<pre>
Then /^I should see a successful sign up message$/ do
page.should have_content "A message with a confirmation link has been sent to your email address."
end
</pre>
<p>You can run <code>rake cucumber</code> to see your failing Cucumber integraton tests.</p>
<p>You’ll have to complete the tutorial before all Cucumber scenarios will run successfully.</p>
<h4>Write Cucumber Scenarios</h4>
<p>To learn more about using Cucumber, refer to <a href="http://pragprog.com/book/hwcuc/the-cucumber-book">The Cucumber Book</a> or the free introduction to Cucumber, <a href="http://cuke4ninja.com/">The Secret Ninja Cucumber Scrolls</a>.</p>
<p>There are two approaches to writing Cucumber scenarios. The newest (and recommended) approach uses <a href="https://github.com/jnicklas/capybara">Capybara</a> to write the code (“steps”) that turn Cucumber scenarios into executable specifications. Older versions of Cucumber provided a <code>web_steps.rb</code> file that implemented common features. See the <a href="http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off">The Training Wheels Came Off</a> by Aslak Hellesøy to understand why the <code>web_steps.rb</code> approach is no longer recommended.</p>
<h2>Test the App</h2>
<p>You can check that your app runs properly by entering the command</p>
<p><code>$ rails server</code></p>
<p>To see your application in action, open a browser window and navigate to <a href="http://localhost:3000">http://localhost:3000/</a>. You should see the Rails default information page.</p>
<p>Stop the server with Control-C.</p>
<h2>Configure Email</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/action_mailer.rb">action_mailer</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>You must configure the app for your email account if you want your application to send email messages, for example, if you’ve generated the application with the option to install the Devise <code>:confirmable</code> module.</p>
<h4>Configure ActionMailer</h4>
<p>Remove the following from the <strong>config/environments/development.rb</strong> file:</p>
<pre>
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
</pre>
<p>Add the following to the <strong>config/environments/development.rb</strong> file:</p>
<pre>
# ActionMailer Config
config.action_mailer.default_url_options = { :host =&gt; 'localhost:3000' }
config.action_mailer.delivery_method = :smtp
# change to false to prevent email from being sent during development
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default :charset =&gt; "utf-8"
</pre>
<p>Add the following to the <strong>config/environments/production.rb</strong> file:</p>
<pre>
config.action_mailer.default_url_options = { :host =&gt; 'example.com' }
# ActionMailer Config
# Setup for production - deliveries, no errors raised
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset =&gt; "utf-8"
</pre>
<p>Add the following to the <strong>config/environments/test.rb</strong> file:</p>
<pre>
# ActionMailer Config
config.action_mailer.default_url_options = { :host =&gt; 'example.com' }
</pre>
<p>This will set the example application to deliver email in both development and production. It will raise delivery errors in development but not production.</p>
<p>In development, <code>config.action_mailer.default_url_options</code> is set for a host at <code>localhost:3000</code> which will enable links in Devise confirmation email messages to work properly during development.</p>
<p>For testing, <code>config.action_mailer.default_url_options</code> is set for a host at <code>example.com</code>. Any value allows tests to run.</p>
<p>For production, you’ll need to change the <code>config.action_mailer.default_url_options</code> host option from <code>example.com</code> to your own domain.</p>
<h4>Use a Gmail account</h4>
<p>If you want to use a Gmail account to send email, you’ll need to modify the files <strong>config/environments/development.rb</strong> and <strong>config/environments/production.rb</strong>:</p>
<pre>
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "example.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
</pre>
<p>You can replace <code>ENV["GMAIL_USERNAME"]</code> and <code>ENV["GMAIL_PASSWORD"]</code> with your Gmail username and password. However, committing the file to a public GitHub repository will expose your secret password.</p>
<p>If you’re familiar with setting <a href="http://en.wikipedia.org/wiki/Environment_variable">Unix environment variables</a>, it’s advisable to leave <code>config.action_mailer.smtp_settings</code> unchanged and set your environment variables in the file that is read when starting an interactive shell (the <strong>~/.bashrc</strong> file for the bash shell). This will keep the password out of your repository.</p>
<p>Are you using a bash shell? Use <code>echo $SHELL</code> to find out. For a bash shell, edit the <strong>~/.bashrc</strong> file and add:</p>
<pre>
export GMAIL_USERNAME="myname@gmail.com"
export GMAIL_PASSWORD="secret*"
</pre>
<p>Open a new shell or restart your terminal application to continue.</p>
<h2>Set Up Authentication</h2>
<p>This app uses <a href="http://github.com/plataformatec/devise">Devise</a> for user management and authentication.</p>
<h4>Set Up Configuration for Devise</h4>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/devise.rb">devise</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>You should have the following gem in your <strong>Gemfile</strong> file:</p>
<pre>
gem 'devise'
</pre>
<p>If you haven’t already, run:</p>
<p><code>$ bundle install</code></p>
<p>Run the generator to install Devise:</p>
<p><code>$ rails generate devise:install</code></p>
<p>which installs a configuration file:</p>
<p><strong>config/initializers/devise.rb</strong></p>
<p>and a localization file:</p>
<p><strong>config/locales/devise.en.yml</strong></p>
<h4>Configure Devise for Email</h4>
<p>Complete your email configuration by modifying</p>
<p><strong>config/initializers/devise.rb</strong></p>
<p>and setting the <code>config.mailer_sender</code> option for the return email address for messages that Devise sends from the application.</p>
<h4>Generate a Model and Routes for Users</h4>
<p>Devise provides all the code needed for a complete user management and authentication system.</p>
<p>Use Devise to generate models and routes for a User.</p>
<pre>
$ rails generate devise User
</pre>
<p>Devise will create a database migration and a User model.</p>
<p>Devise will try to create a spec file for the User model. If you’ve already downloaded the example app spec files, don’t let the Devise generator overwrite the <strong>spec/models/user_spec.rb</strong> file (enter “n” to prevent overwriting).</p>
<p>Devise will try to create factories for testing the User model. You’ve already created a <strong>spec/factories/users.rb</strong> file, do don’t let the Devise generator overwrite the <strong>spec/factories/users.rb</strong> file (enter “n” to prevent overwriting).</p>
<p>Devise will modify the <strong>config/routes.rb</strong> file to add:</p>
<pre>
devise_for :users
</pre>
<p>which provides a complete set of routes for user signup and login. If you run <code>rake routes</code> you can see the routes that this line of code creates.</p>
<h4>Accommodate Cucumber Testing for “Sign Out”</h4>
<p>By default, Devise uses an http <span class="caps">DELETE</span> request for sign out requests (<code>destroy_user_session_path</code>). Rails uses Javascript to implement http <span class="caps">DELETE</span> requests. Prior to Devise 1.4.1 (27 June 2011), Devise used an http <span class="caps">GET</span> request for sign out requests. Jose Valim explained the change: “<span class="caps">GET</span> requests should not change the state of the server. When sign out is a <span class="caps">GET</span> request, <span class="caps">CSRF</span> can be used to sign you out automatically and things that preload links can eventually sign you out by mistake as well.”</p>
<p>However, Cucumber wants to test <span class="caps">GET</span> requests not <span class="caps">DELETE</span> requests. If you intend to use Cucumber with Devise, you must change the Devise default from <span class="caps">DELETE</span> to <span class="caps">GET</span> in <strong>/config/initializers/devise.rb</strong> for the Rails test environment. You may see a suggestion elsewhere to tweak the routes.rb file or change the log_out link to make the fix. It isn’t necessary if you change the <strong>/config/initializers/devise.rb</strong> file.</p>
<pre>
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = Rails.env.test? ? :get : :delete
</pre>
<p>Since you only use Cucumber during testing, switching the default is only needed for testing.</p>
<p>If you’re not going to use Cucumber, leave Devise’s default (<span class="caps">DELETE</span>) in place.</p>
<h4>Prevent Logging of Passwords</h4>
<p>We don’t want passwords written to our log file.</p>
<p>Modify the file <strong>config/application.rb</strong> to include:</p>
<p><code>config.filter_parameters += [:password, :password_confirmation]</code></p>
<p>Note that filter_parameters is an array.</p>
<h2>Customize the Application</h2>
<h4>Enable Users to Have Names</h4>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/add_user.rb">add_user</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>By default, Devise uses an email address to identify users. We’ll add a “name” attribute as well. Your application may not require a user to provide a name. But showing you how to add a name will help you see what you need to do if you decide to make changes to the default Devise user model.</p>
<p>Devise created a migration file to establish the schema for the SQLite database with a migration file named something like <strong>db/migrate/xxxxxxx_devise_create_users.rb</strong>. We won’t modify the migration file. Instead we’ll add an additional migration that adds the “name” field to the User record.</p>
<pre>
rails generate migration AddNameToUsers name:string
</pre>
<p>Run the migration and prepare the test database to pick up the “name” field:</p>
<pre>
$ bundle exec rake db:migrate
$ bundle exec rake db:test:prepare
</pre>
<p>If you wish, you can modify the user model to validate the presence and uniqueness of the “name” attribute. Modify the file <strong>app/models/user.rb</strong> and add:</p>
<pre>
validates_presence_of :name
validates_uniqueness_of :name, :email, :case_sensitive =&gt; false
</pre>
<p>This will allow users to be created (or edited) with a name attribute. When a user is created, a name and email address must be present and must be unique (not used before). Note that Devise (by default) will check that the email address and password are not blank and that the email address is unique.</p>
<p>You’ll also want to prevent malicious hackers from creating fake web forms that would allow changing of passwords through the mass-assignment operations of update_attributes(attrs) and new(attrs). Devise already added this to the <strong>models/user.rb</strong> file:</p>
<pre>
attr_accessible :email, :password, :password_confirmation, :remember_me
</pre>
<p>but you’ll need to add the “name” attribute:</p>
<pre>
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
</pre>
<p>If you’ve chosen to create the application with the Devise Confirmable module, also add <code>:confirmed_at</code>:</p>
<pre>
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :confirmed_at
</pre>
<h4 id="registration-views">Create Customized Views for User Registration (<span class="caps">ERB</span>)</h4>
<p>Devise provides a controller and views for registering users. It is called the “registerable” module. The controller and views are hidden in the Devise gem so we don’t need to create anything. However, because we want our users to provide a name when registering, we will create custom views for creating and editing a user. Our custom views will override the Devise gem defaults.</p>
<p>First, to copy all the default Devise views to your application, run</p>
<p><code>rails generate devise:views</code></p>
<p>This will generate a set of views in the directory <strong>app/views/devise/</strong>.</p>
<p>Next, modify the views to create and edit users.</p>
<p>Add the following code to each file:</p>
<p><strong>app/views/devise/registrations/edit.html.erb</strong></p>
<pre>
&lt;p&gt;&lt;%= f.label :name %&gt;&lt;br /&gt;
&lt;%= f.text_field :name %&gt;&lt;/p&gt;
</pre>
<p><strong>app/views/devise/registrations/new.html.erb</strong></p>
<pre>
&lt;p&gt;&lt;%= f.label :name %&gt;&lt;br /&gt;
&lt;%= f.text_field :name %&gt;&lt;/p&gt;
</pre>
<p>We do not need to add a controller with methods to create a new user or edit or delete a user. We use the existing “registerable” module from Devise which provides a controller with methods to create, edit or delete a user.</p>
<p>Note that Devise’s default behaviour allows any logged-in user to edit or delete his or her own record (but no one else’s). When you access the edit page you are editing just your info, and not info of other users.</p>
<h4>Create Customized Views for User Registration (Haml)</h4>
<p>If you are using Haml, Devise does not generate views for Haml (it did before Devise 1.2; see <a href="https://github.com/plataformatec/devise/issues/878">Devise issue 878</a>). See <a href="https://github.com/plataformatec/devise/wiki/How-To:-Create-Haml-and-Slim-Views">How To Create Haml and Slim Views</a> from the Devise wiki.</p>
<p>If you are using Haml, you can generate the <span class="caps">ERB</span> files using <code>rails generate devise:views</code> and then convert them using the online tool <a href="http://html2haml.heroku.com/">Html2Haml</a>. You’ll need to remove the <strong>.erb</strong> files and replace them with <strong>app/views/devise/registrations/edit.html.haml</strong> and <strong>app/views/devise/registrations/new.html.haml</strong>.</p>
<h2>Create a Home Page</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/home_page.rb">home_page</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<h4>Remove the Default Home Page</h4>
<p>Delete the default home page from your application:</p>
<p><code>$ rm public/index.html</code></p>
<h4>Create a Home Controller and View</h4>
<p>Create the first page of the application. Use the Rails generate command to create a “home” controller and a “views/home/index” page. Specify <code>--no-controller-specs</code> to avoid overwriting the RSpec files you’ve already downloaded.</p>
<p><code>$ rails generate controller home index --no-controller-specs</code></p>
<p>If you’re using the default template engine, you’ll find an <strong>erb</strong> file with placeholder content:</p>
<p><strong>app/views/home/index.html.erb</strong></p>
<p>Next, set a route to your home page. Edit the file <strong>config/routes.rb</strong> and replace:</p>
<p><code>get "home/index"</code></p>
<p>with</p>
<pre>
authenticated :user do
root :to =&gt; 'home#index'
end
root :to =&gt; "home#index"
</pre>
<p>If you examine this code, you’ll see that authenticated users (those who have an account and are logged in) will see the home/index page as the application root (or home) page. And all other users (those who don’t have an account or who are not logged in) will see the same home page. The redundancy serves a didactic purpose: If you decide you want users to see a different page when they log in, you now know exactly where to change it.</p>
<p>By default, Devise will redirect to the root_path after successful sign in or sign out. It is easy to change the root_path as shown in the <strong>config/routes.rb</strong> file. Alternatively, you can override the Devise methods <code>after_sign_in_path_for</code> and <code>after_sign_out_path_for</code> as described in the Devise wiki article <a href="https://github.com/plataformatec/devise/wiki/How-To%3A-Redirect-to-a-specific-page-on-successful-sign-in-out">How To Redirect to a Specific Page</a>.</p>
<h4>Test the App</h4>
<p>You can check that your app runs properly by entering the command</p>
<p><code>$ rails server</code></p>
<p>To see your application in action, open a browser window and navigate to <a href="http://localhost:3000">http://localhost:3000/</a>. You should see your new home page.</p>
<p>Stop the server with Control-C.</p>
<h2>Display Users on the Home Page</h2>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/home_page_users.rb">home_page_users</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>Modify the file <strong>app/controllers/home_controller.rb</strong> and add:</p>
<pre>
def index
@users = User.all
end
</pre>
<p>Modify the file <strong>app/views/home/index.html.erb</strong> and add:</p>
<pre>
&lt;h3&gt;Home&lt;/h3&gt;
&lt;% @users.each do |user| %&gt;
&lt;p&gt;User: &lt;%= user.name %&gt; &lt;/p&gt;
&lt;% end %&gt;
</pre>
<p>This code is not appropriate for deployment in a real application. You likely will not want to display a list of users on the home page. However, it is convenient for our example.</p>
<h2>Create a Default User</h2>
<h4>Set Up a Database Seed File</h4>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/seed_database.rb">seed_database</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>You’ll want to set up a default user so you can test the app. Modify the file <strong>db/seeds.rb</strong> by adding:</p>
<pre>
puts 'SETTING UP DEFAULT USER LOGIN'
user = User.create! :name =&gt; 'First User', :email =&gt; 'user@example.com', :password =&gt; 'please', :password_confirmation =&gt; 'please'
puts 'New user created: ' &lt;&lt; user.name
user2 = User.create! :name =&gt; 'Second User', :email =&gt; 'user2@example.com', :password =&gt; 'please', :password_confirmation =&gt; 'please'
puts 'New user created: ' &lt;&lt; user2.name
</pre>
<p>If you’ve chosen to create the application with the Devise Confirmable module, add the field <code>confirmed_at</code>:</p>
<pre>
puts 'SETTING UP DEFAULT USER LOGIN'
user = User.create! :name =&gt; 'First User', :email =&gt; 'user@example.com', :password =&gt; 'please', :password_confirmation =&gt; 'please', :confirmed_at =&gt; DateTime.now
user2 = User.create! :name =&gt; 'Second User', :email =&gt; 'user2@example.com', :password =&gt; 'please', :password_confirmation =&gt; 'please', :confirmed_at =&gt; DateTime.now
puts 'New user created: ' &lt;&lt; user.name
</pre>
<p>You can change the values for name, email, and password as you wish.</p>
<h4>Seed the Database</h4>
<p>Add the default user to the database by running the command:</p>
<p><code>$ bundle exec rake db:seed</code></p>
<p>If you need to, you can run <code>$ bundle exec rake db:reset</code> to drop and then recreate the database using your seeds.rb file.</p>
<p>If the task fails with “Validation failed: Name can’t be blank” you should check that the file <strong>models/user.rb</strong> allows the “name” attribute to be mass updated:</p>
<pre>
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
</pre>
<h4>Test the App</h4>
<p>At this point, you may want to know if the default user has been saved to the database.</p>
<p>You can check that your app runs properly by entering the command</p>
<p><code>$ rails server</code></p>
<p>To see your application in action, open a browser window and navigate to <a href="http://localhost:3000">http://localhost:3000/</a>. You should see your new home page with a list of all the users.</p>
<p>Stop the server with Control-C.</p>
<h2>Set Up a Demonstration of Devise</h2>
<p>You’ll want to see how Devise manages authentication.</p>
<h4>Set Up the Users Controller, Views, and Routes</h4>
<p><em>If you are creating an application template, this step uses the <a href="https://raw.github.com/RailsApps/rails_apps_composer/master/recipes/users_page.rb">users_page</a> recipe from the <a href="https://github.com/RailsApps/rails_apps_composer">rails_apps_composer</a> repository</em></p>
<p>Use the Rails generate command to create a “users” controller and a “views/user/show” page. Specify <code>--no-controller-specs</code> to avoid overwriting the RSpec files you’ve already downloaded.</p>
<p><code>$ rails generate controller users index show --no-controller-specs</code></p>
<p>Note that “users” is plural when you create the controller.</p>
<p>Modify the file <strong>app/controllers/users_controller.rb</strong> like this:</p>
<pre>
class UsersController &lt; ApplicationController
before_filter :authenticate_user!
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
end
</pre>
<p>The file <strong>config/routes.rb</strong> has been modified to include:</p>
<pre>
get "users/index"
get "users/show"
</pre>
<p>Remove that and change the routes to:</p>
<pre>
authenticated :user do
root :to =&gt; 'home#index'
end
root :to =&gt; "home#index"
devise_for :users
resources :users, :only =&gt; [:show, :index]
</pre>
<p>Important note: The <code>devise_for :users</code> route must be placed above <code>resources :users, :only =&gt; [:show, :index]</code>.</p>
<p>Modify the file <strong>app/views/users/show.html.erb</strong> and add:</p>
<pre>
&lt;p&gt;User: &lt;%= @user.name %&gt;&lt;/p&gt;
&lt;p&gt;Email: &lt;%= @user.email if @user.email %&gt;&lt;/p&gt;
</pre>
<p>Modify the file <strong>app/views/users/index.html.erb</strong> and add:</p>
<pre>
&lt;ul class="users"&gt;
&lt;% @users.each do |user| %&gt;
&lt;li&gt;
&lt;%= link_to user.name, user %&gt; signed up &lt;%= user.created_at.to_date %&gt;
&lt;/li&gt;
&lt;% end %&gt;
&lt;/ul&gt;
</pre>
<h4>Add Links to Users on the Home Page</h4>
<p>You’ve already modified the file <strong>app/controllers/home_controller.rb</strong> to include this:</p>
<pre>
def index
@users = User.all
end
</pre>
<p>Now modify the file <strong>app/views/home/index.html.erb</strong> to look like this:</p>
<pre>
&lt;h3&gt;Home&lt;/h3&gt;
&lt;% @users.each do |user| %&gt;
&lt;p&gt;User: &lt;%=link_to user.name, user %&gt;&lt;/p&gt;
&lt;% end %&gt;
</pre>
<h2>Create an Application Layout</h2>
<p>Rails will use the layout defined in the file <strong>app/views/layouts/application.html.erb</strong> as a default for rendering any page. If you are using Haml, the file will be <strong>app/views/layouts/application.html.haml</strong>.</p>
<p>You’ll want to add navigation links, include flash messages for errors and notifications, and apply <span class="caps">CSS</span> styling. Set up your application layout by modifying the default as described in the instructions for the <a href="http://railsapps.github.com/rails-default-application-layout.html">Rails default application layout</a>.</p>
<p>You can use Twitter Bootstrap or another <span class="caps">CSS</span> front-end framework to provide styling. If you’ve generated the app from an application template, the script will offer you Twitter Bootstrap and other choices.</p>
<h2>Cleanup</h2>
<p>Several unneeded files are generated in the process of creating a new Rails application.</p>
<p>Additionally, you may want to prevent search engines from indexing your website if you’ve deployed it publicly while still in development.</p>
<p>See instructions for <a href="http://railsapps.github.com/rails-cleanup.html">cleaning up unneeded files in Rails and banning spiders</a>.</p>
<h2>Run Unit and Integration Tests</h2>
<p>The application is complete. Run your unit and integration tests to see if the application is implemented as intended.</p>
<p>Run <code>rake spec</code> to see the unit tests. You should see no tests failing.</p>
<p>Run <code>rake cucumber</code> to see your Cucumber integration tests. You should see all scenarios passing.</p>
<h2>Test the App</h2>
<p>You can check that your app runs properly by entering the command</p>
<p><code>$ rails server</code></p>
<p>To see your application in action, open a browser window and navigate to <a href="http://localhost:3000">http://localhost:3000/</a>. You should see the default user listed on the home page. When you click on the user’s name, you should be required to log in before seeing the user’s detail page.</p>
<p>Stop the server with Control-C.</p>
<h2>Deploy to Heroku</h2>
<p>Heroku provides low cost, easily configured Rails application hosting. For your convenience, see <a href="http://railsapps.github.com/rails-heroku-tutorial.html">Tutorial: Rails on Heroku</a>.</p>
<h2>Conclusion</h2>
<p>This concludes the tutorial for creating a Ruby on Rails web application that requires Rails and uses Devise for user management and authentication with RSpec and Cucumber.</p>
<h4>Credits</h4>
<p>Daniel Kehoe implemented the application and wrote the tutorial.</p>
<p>Was this useful to you? Follow <a href="http://twitter.com/rails_apps">rails_apps</a> on Twitter and tweet some praise. I’d love to know you were helped out by the tutorial.</p>
<p>Any issues? Please create an <a href="http://github.com/RailsApps/rails3-devise-rspec-cucumber/issues">Issue</a> on GitHub.</p>
</div><!-- class="content" -->
<div class="comments">
<div class="content wikistyle gollum">
<h2>Comments and Issues</h2>
</div>
<p>Is this helpful? Please add a comment below. Your encouragement fuels the project.</p>
<p>Did you find an error? Or couldn't get something to work? For the example apps and tutorials, please create a GitHub issue in the repository for the example app. Creating a GitHub issue is the best way to make sure a problem is investigated and fixed.</p>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'railsapps'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</div><!-- class="comments" -->
<div class="footer row">
<div class="span4">
<h3>Credits</h3>
<p><a href="http://danielkehoe.com/">Daniel Kehoe</a> initiated the <a href="http://railsapps.github.com/">RailsApps Project</a>. Thanks to all the users and contributors.</p>
</div>
<div class="span4">
<h3>Wiki</h3>
<p>Corrections? Additions? You can edit this page <a href="https://github.com/RailsApps/railsapps.github.com/wiki/_pages">on the wiki</a>.</p>
</div>
<div class="span4">
<h3>Last edit</h3>
<p>by <b>Daniel Kehoe</b>, 2012-07-20 23:08:42</p>
</div>
</div>
</div>
</body>
</html>