Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 261 lines (174 sloc) 9.251 kb

Skeleton for new Rails 3 based application

Dependency Status

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

Gems

Initializes

  • config.rb - shortcut for getting application config with `app_config`

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

  • simple_form.rb - setup simple_form options

  • 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 example.com domain, used only in the development and test environments

  • bullet.rb - setup bullet

  • airbrake.rb - setup airbrake API key from ENV

Quick start

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

git clone git://github.com/fs/rails3-base.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 git@github.com:[MY-GITHUB-ACCOUNT]/[MY-NEW-PROJECT].git
git push -u origin master

Setup configuration files

cp .env.example .env
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/

Application configuration

Different application configurations could be stored in different places:

  • `config/initializers/*.rb` - gem related settings.

  • `config/application.rb` - default settings for all environments.

  • `config/environments/*.rb` - overwrite settings for specified environment .

  • `.env` for setting environment variables like API tokens, they will be loaded on application load into ENV.

Authorization

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.

Scaffolding

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

Tests

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

Rspec

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 }
end

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 = DemoMan.new
  end

  subject { @demo_man }

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

(Over)use describe and context

describe User do
  before { @user = User.new }

  subject { @user }

  context "when name empty" do
    it { should not be_valid }
    specify { @user.save.should == false }
  end

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

    it { should be_valid }
    specify { @user.save.should == true }
  end

  describe :present do
    subject { @user.present }

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

      it { should be_a Flower }
    end

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

      it { should be_an IMac }
    end
  end
end

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"
  end
end

eggsonbread.com/2010/03/28/my-rspec-best-practices-and-tips/

Cucumber features

Organization

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:

Background:
  Given I am an authenticated user

Tags

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 user.email” in your shell), mail safe will use this. All emails will be sent to this address except @example.com, 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.

Jump to Line
Something went wrong with that request. Please try again.