Skeleton for new Rails 3 based projects
Pull request Compare This branch is 316 commits ahead, 1237 commits behind fs:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Skeleton for new Rails 3 based application

This simple application includes ruby/rails technology which we use in the FlatStack for new projects. Application currently based on Rails 3.2 stable branch and Ruby 1.9



  • configatron.rb - loads configuration for current Rails environment to the configatron, so you can access them like configatron.app_name

  • devise.rb - setup devise options, mailer_sender and pepper from config

  • simple_form.rb - setup simple_form options

  • tabletastic.rb - setup tabletastic options, by default all actions rendered in the list

  • mailer.rb - setup default hosts for mailer from configuration

  • simple_navigation.rb - setup simple navigation options

  • time_formats.rb - setup default time formats, so you can use them like object.create_at.to_s(:us_time)

  • requires.rb - automatically requires everything in lib/ & lib/extensions

  • mail_safe.rb - allow sending emails to the domain, used only in the development and test environments

Quick start

Clone application as new project with original repository named “rails3-base”

git clone git:// --origin rails3-base [MY-NEW-PROJECT]

Create your new repo on GitHub and push master into it. Make sure master branch is tracking origin repo.

git remote add origin[MY-GITHUB-ACCOUNT]/[MY-NEW-PROJECT].git
git push -u origin master

Setup configuration files

cp config/database.yml.example config/database.yml

Install gems and enable rvm integration with Bundler (the “bin” directory is added to your path each time you cd into a project directory with binstubs)

bundle install --path vendor --binstubs
chmod +x $rvm_path/hooks/after_cd_bundler

Make sure all test are green

bundle exec rake spec cucumber

How to update existing project with new changes from rails3-base repo

You can fetch latest changes from rails3-base repo and merge or cherry-pick commits

git fetch rails3-base
git flow feature start rails3-base-update
git merge rails3-base/master

# fix conflicts
# commit
# test

git flow feature finish rails3-base-update

Gem management

Instead of using RVM gemset for isolating gems for your new Rails application it's better to use bundler “path” option:

bundle install --path vendor --binstubs

will install all gems into the vendor/ruby and all executables to bin/


We use Devise for login based auth b/c is modular and have a good community support. Take a look at config/initializers/devise.rb if you want customize it.


Scaffold generator will create: model with rspec, factory, controller based on inherited resources, views based on formtastic & tabletastic.

$ rails g scaffold post title:string text:text

Cucumber:feature generator will create: cucumber feature for scaffold resource

$ rails g cucumber:feature post title:string text:text


We use rspec with shoulda matchers for model testing and cucumber with capybara for integration testing.


You should cover validations, associations with shoulda matchers and test deeply complected model methods. Check out for example user_spec.rb

describe User do
  it { should allow_mass_assignment_of(:full_name) }
  it { should allow_mass_assignment_of(:email) }
  it { should allow_mass_assignment_of(:password) }
  it { should allow_mass_assignment_of(:password_confirmation) }

  it { should validate_presence_of :full_name }

Use shortcuts specify {}, it {} and subject {}

subject { @user.address }
it { should be_valid }

Start context with ‘when’/'with’ and methods description with ‘#’

Use RSpec matchers to get meaningful messages

specify { user.should be_valid }

Only one expectation per it block

describe DemoMan do
  before(:all) do
    @demo_man =

  subject { @demo_man }

  it { should respond_to :name   }
  it { should respond_to :gender }
  it { should respond_to :age    }

(Over)use describe and context

describe User do
  before { @user = }

  subject { @user }

  context "when name empty" do
    it { should not be_valid }
    specify { == false }

  context "when name not empty" do
    before { = 'Sam' }

    it { should be_valid }
    specify { == true }

  describe :present do
    subject { @user.present }

    context "when user is a W" do
      before { @user.gender = 'W' }

      it { should be_a Flower }

    context "when user is a M" do
      before { @user.gender = 'M' }

      it { should be_an IMac }

Test Valid, Edge and Invalid cases

describe "#month_in_english(month_id)" do
  context "when valid" do
    it "should return 'January' for 1" # lower boundary
    it "should return 'March' for 3"
    it "should return 'December' for 12" # upper boundary
  context "when invalid" do
    it "should return nil for 0"
    it "should return nil for 13"

Cucumber features


Group steps by model. We’ve found the best way to keep track of them is to group them by the primary model they affect. Some steps may affect multiple models, but usually there is an obvious choice.

Put each feature in it’s own file. Don’t be afraid to put features in subdirectories. For any large app, it’s almost essential.

Keep the file organized grouping the steps by Given / When / Then.

Custom steps make your scenario DRY and accessible

Scenarios should have the same lifecyle as your code: Red, Green, Refactor to make them DRY and easy to read.

Background: setup the DRY way

Make the feature focus on one business object/action/context and the background will get longer than the scenarios.

Use 'Background' to consolidate common steps in a feature:

  Given I am an authenticated user


You can use @webmock for enabling webmock functionality around some scenario. It's mean all real HTTP connection will be disabled in the given scenario and you need to stub them with stub_request.

Mail Safe

Mail safe provides a safety net while you’re developing an application that uses ActionMailer. It keeps emails from escaping into the wild.

Once you’ve installed and configured this gem, you can rest assure that your app won’t send emails to external email addresses. Instead, emails that would normally be delivered to external addresses will be sent to an address of your choosing, and the body of the email will be appended with a note stating where the email was originally intended to go.

If you have git installed, and you’ve registered your email address with it (check with “git config” in your shell), mail safe will use this. All emails will be sent to this address except, checkout config/initializers/mail_safe.rb

Checkout also:

Simple Navigation

Navigation configuration stored in the config/navigations folder. We have main and user navigation which accessible for visitor and authorized user accordingly.

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don't break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send a pull request. Bonus points for topic branches.

© FlatStack