Skip to content

Instantly share code, notes, and snippets.

@alekpopovic
Forked from pboksz/creating-new-rails-app.md
Last active August 29, 2015 14:24
Show Gist options
  • Save alekpopovic/0523af886af7d80e8b9a to your computer and use it in GitHub Desktop.
Save alekpopovic/0523af886af7d80e8b9a to your computer and use it in GitHub Desktop.

Creating a new Rails app with Rspec, Backbone, Jasmine

NOTE: This guide assumes that you already have ruby, rails, and mysql installed on your machine, and have an IDE or code editing tool (VIM!) all ready to go.

Creating the app

First thing's first. Rails makes it nice and simple to create a new app with the proper directory structure (lets assume we are calling this app “luna” and our directory with projects is “projects”):

$ cd projects
$ rails new luna

Adding neccessary gems

Next, open the Gemfile and add any gems that you need or want. Here is a what my initial gemfile would look like, noting that a lot of the gem inclusions are based on how I like to work, and more specifically, how I like to test my apps.

source 'https://rubygems.org'

gem 'rails', '3.2.6'
gem 'mysql2'

gem 'backbone-on-rails' # backbone.js
gem 'bcrypt-ruby' # salting and hashing passwords
gem 'debugger' # for debugging in rails
gem 'devise' # for user authentication
gem 'execjs' # javascript runtime
gem 'jquery-rails' # jquery!
gem 'json' # json!
gem 'therubyracer' # javascript runtime
gem 'thin' # or unicorn, passenger, etc
gem 'underscore-rails' # underscore.js

group :assets do
	gem 'coffee-rails', '~> 3.2.1' # for working with coffeescript
	gem 'sass-rails',   '~> 3.2.3' # for working with scss files
	gem 'uglifier', '>= 1.0.3' # for js file compression
end

group :test do
	gem 'capybara' # for integration specs that require interacting with rails views
	gem 'database_cleaner' # for clearing the database before and after specs
end

group :development do
	gem 'better_errors' # for showing more detailed error pages
	gem 'bullet' # for checking N+1 queries, counter caching, and eager loading, turn on after you get stuff going
end

group :development, :test do
	gem 'capistrano' # for running deploy scripts
	gem 'factory_girl_rails' # for creating models in specs
	gem 'jasminerice' # for coffeescript specs in rails
	gem 'rspec-rails' # respec for rails
	gem 'spork-rails' # for quickly running spec on a dedicated port
end

Once that is done run bundle to download all the gems. There may be some dependency issues with things that you need installed on your local machine, so just follow the instructions given by the error messages (usually you need to $sudo apt-get install$ something) or google the error to see what needs to be done.

Setting up the database

Create the databases:

$ echo "create database luna_development" | mysql -u root -p
$ echo "create database luna_test" | mysql -u root -p

Now grant all privileges to a user (in this case called “luna”) for both databases. This will also create the user if it is not already created. Note that if you want to have a password on this user, add “... identified by ‘password’” before the pipe the first time you run this command:

$ echo "grant all on luna_development.* to luna@localhost" | mysql -u root -p
$ echo "grant all on luna_test.* to luna@localhost" | mysql -u root -p

Next double check that everything has been created:

$ echo "show databases" | mysql -u luna -p

You should be looking a list of the databases that the user “luna” has privileges on. This list should include “luna_development” and “luna_test”. If thats the case, exit mysql.

Configuring the database.yml file

Next open up the project in the IDE or coding tool of your choice and find the “config/database.yml” file. Configure the mysql database with the information that you just set up in the database. The file should look something like this:

development:
	adapter: mysql2
	encoding: utf8
	database: luna_development
	username: luna
	password:
	host: localhost
	
test:
	adapter: mysql2
	encoding: utf8
	database: luna_test
	username: luna
	password:
	host: localhost

Now, copy this file into the same folder and rename it “database.yml.sample”. Now open up the “.gitignore” file and add “database.yml”. Making sure that personal password, hell, passwords of any kind, do not get commited into a repo is important. And you do this creating a copy of any file that has passwords in it, removing the passwords, and appending .sample to the name. The .sample files will be commited and will give anyone working with you an example of how the configuration file should look, but without any of your personal passwords.

In your project directory delete the entire test directory and then install rspec:

$ rm -r test
$ rails g rspec:install

This should create the “.rspec” file and the “spec” directory with “spec_helper.rb” inside it. Open up "config/application.rb" and add the "config.generators" line so the file looks like this:

module Luna
	class Application < Rails::Application
		#...
		config.generators.test_framework = :rspec
		#...
	end
end

Next, bootstrap spork off of rspec:

$ spork rspec --bootstrap

This will edit the “spec_helper.rb” file. Open that one up. Now there should be a two blocks:

Spork.prefork.do
	# many comments
end

Spork.each_run do
end

# huge block of comments

Put everything under the huge block of comments into the Spork.prefork block. Now go through it and make sure to add some requires under the ones that are already there, uncomment the mocha mock framework, and add a bunch of config options in the RSpec.configuration block, and the "requires" so your file looks like this:

require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'

Spork.prefork do
	# Loading more in this block will cause your tests to run faster. However,
	# if you change any configuration or code from libraries loaded here, you'll
	# need to restart spork for it take effect.
	
	# 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 'rspec/autorun'
	require 'capybara/rails'
	require 'capybara/rspec'
	require 'database_cleaner'

	# Requires supporting ruby files with custom matchers and macros, etc,
	# in spec/support/ and its subdirectories.
  	Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

	RSpec.configure do |config|
		# ## Mock Framework
		#
		# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
		#
		config.mock_with :mocha
		# config.mock_with :flexmock
		# config.mock_with :rr
		
		# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
		config.fixture_path = "#{::Rails.root}/spec/fixtures"
		
		# If you're not using ActiveRecord, or you'd prefer not to run each of your
		# examples within a transaction, remove the following line or assign false
		# instead of true.
		config.use_transactional_fixtures = true
		
		# If true, the base class of anonymous controllers will be inferred
		# automatically. This will be the default behavior in future versions of
		# rspec-rails.
		config.infer_base_class_for_anonymous_controllers = false
		
		# Run specs in random order to surface order dependencies. If you find an
		# order dependency and want to debug it, you can fix the order by providing
		# the seed, which is printed after each run.
		#     --seed 1234
		config.order = "random"
		
		# this fixes something, if I remember correctly
		config.treat_symbols_as_metadata_keys_with_true_values = true
		
		# so you dont have to write FactoryGirl.create(...) every time
		config.include FactoryGirl::Syntax::Methods
		
		# make output colorful
		config.color_enabled = true
		
		config.before(:suite) do
			DatabaseCleaner.strategy = :transaction
			DatabaseCleaner.clean_with(:truncation)
		end
	
		config.before(:each) do
			DatabaseCleaner.start
		end
	
		config.after(:each) do
			DatabaseCleaner.clean
		end
	end
end

Spork.each_run do
	# This code will be run each time you run your specs.

	# This is so when you change FactoryGirl factories you dont have to exit and reload spork
	FactoryGirl.reload
end

Next, create a folder "/spec/features" to keep your Capybara specs in. Now if you go back to the console and run rspec spec you should see an output saying “No examples found. 0 examples, 0 failures.” This means that rspec is all good.

Configure [FactoryGirlRails] to automatically create factories on model generation

Open up "config/application.rb" and add the "config.generators" line so the file looks like this:

module Luna
	class Application < Rails::Application
		#...
		config.generators.fixture_replacement :factory_girl
		#...
	end
end

Now generating a model will automatically create a factory to be used in specs.

Configure Jasminerice

Installing jasminerice should be a matter of running one command:

$ rails g jasminerice:install

Next, open up "/spec/javascripts/spec.js.coffee" and add make sure your file looks like this by adding a line:

# This pulls in all your specs from the javascripts directory into Jasmine:
# 
# spec/javascripts/*_spec.js.coffee
# spec/javascripts/*_spec.js
# spec/javascripts/*_spec.js.erb
# IT IS UNLIKELY THAT YOU WILL NEED TO CHANGE THIS FILE
#
#=require application
#=require_tree ./

That should be it to get jasmine up and ready for writing tests for you backbone collections, models, views, and anything else by adding specs to the "spec/javascripts/" folder and going to "localhost:3000/jasmine" when rails server is up and running.

Using Devise to make a User model for the app

Next up is creating a User model with authentication for your app. First install Devise:

$ rails g devise:install

As per the message that devise display’s you should open up “config/routes.rb” and put a starting route in. Just like devise says, you should put this line into the route file somewhere in this block:

Luna::Application.routes.draw do
	root :to => 'home#index'
	#...
end

Also, it says to put this line into “config/application.rb”:

module Luna
	class Application < Rails::Application
		#...
		config.assets.initialize_on_precompile = false
		#...
	end
end

The last thing that devise mentions is the command:

$ rails g devise:views

Which may come in handy if you want to change how devise looks, or what features it has, but we can hold off on that now. Next, run the devise model generation command:

$ rails g devise User name:string

This should add a bunch of files including a "db/migration/...", a User model, a User spec, a User factory, and add a devise route for User in "config/routes.rb". After this make sure to run rake to create and then migrate the db.

$ rake db:create
$ rake db:migrate
$ rake db:migrate RAILS_ENV=test
$ rails g backbone:install

This command should create a whole bunch of directories in "app/assets/javascript", which are "models", "collections", "routers", "views". It also creates another file in that directory, "luna.js.coffee" and will modify "application.js" to have all the neccessary requirements (including underscore!). It also creates a directory "app/assets/templates" where you will put all the templates used for Backbone. The next command is like the rails g model user command for rails, but it creates a Backbone model, collection, router, view, and template:

$ rails g backbone:scaffold user

Configure Bullet for future use

Bullet is a gem that shows you N+1 queries, missing counter caches, and unused eager loading in your app. It is great to use later on when you have some models and you want to see if you can optimize your page loads. In the "config/environments/development.rb" file add the following block so the file looks like this:

BaseRailsProject::Application.configure do
	#...
	config.after_initialize do
		# Uncomment the next line to test queries in your development environment
		#Bullet.enable = true
		Bullet.bullet_logger = true
		Bullet.console = true
	end
end

This will enable Bullet only if you uncomment that line when you are ready for testing. And Bullet will only run in the development environment.

And you are done!

Now you have a user with authentication, an avatar attachment, and all the test files ready in both Rails and Backbone. After this last step you should be ready for programming (and hopefully doing some TDD)!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment