Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Skeleton for new Rails based projects

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
app
config
db
doc
features
lib
public
script
spec
vendor/plugins
.gitignore
.rspec
.rvmrc
.simplecov
.travis.yml
Gemfile
Gemfile.lock
Guardfile
README.rdoc
Rakefile
config.ru

README.rdoc

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 stable branch.

Gems

Initializes

  • 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 example.com 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://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

config/configatron/development.rb
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/

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.

We use Omniauth for authientification over OAuth with Twitter. Please configure key & secret token in the config/config.yml If you don't want to use omniauth simply comment it's configuration in the config/initializers/devise.rb

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. Checkout twitter_authentication_steps.rb for example.

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.

© FlatStack

Something went wrong with that request. Please try again.