It’s easy enough to set up a staging environment on Heroku and have the environment use your staging.rb at runtime by setting the RACK_ENV variable to “staging”.
Currently there is a problem if you need anything from your staging.rb whilst the slug is being compiled. I ran into this when I specified an asset host. At runtime, assets that were referenced in the rails code were fine, but all assets referenced in my stylesheets pointed at the asset host from the production.rb.
With the default set up, environment variables are ignored during slug compilation. There is a setting in heroku labs that will load the variables before slug compilation:
As with anything in labs, there are no guarantees, butI have had no problems so far.
If you’re hosting your app on Heroku (possibly even if you aren’t) it is a good idea to create a staging environment also. Heroku has docs on this but the short version for a new app is:
heroku create staging-app-name --stack cedar --remote staging(if the app is already on Heroku, just add the remote:
git remote add staging git-url-on-heroku)
git push staging master
heroku rake db:migrate --remote staging
heroku rake db:seed --remote staging
Hopefully you have a staging environment set in config/environments/staging.rb so:
heroku config:add RAKE_ENV=staging --remote staging
heroku config:add RAILS_ENV=staging --remote staging
If you want to push a different branch to staging such as develop:
git push staging develop:master
Once staging is set, create the production app in the same way:
heroku create app-name --stack cedar --remote production
git push production master
heroku rake db:migrate --remote production
heroku rake db:seed --remote production
Using the guard gem to run tests etc in your Rails app normally requires some form of file system monitoring.
The monitoring will be OS dependant and rb-fsevent is the gem for OSX. This can be added to the Gemfile conditionally with:
gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
Unfortunately when you next push to Heroku you are likely to get an error along the lines of:
This is due to Heroku not allowing conditions in the Gemfile, even in the dev group.
The alternative is to put the gem in it’s own group:
And on non Mac systems run
bundle install --without darwin (this only needs to be run once, the without setting is remembered for future bundle installs). Then for Heroku run
heroku config:add BUNDLE_WITHOUT="development test darwin"
Don’t forget to add –remote remote_name if you are pushing to a remote other than heroku (e.g.
heroku config:add BUNDLE_WITHOUT="development test darwin" --remote staging) and don’t forget to merge your amended Gemfile into master before running
git push heroku master.
https://github.com/ddollar/heroku-accounts is a plugin for Heroku to allow you to use multiple accounts, e.g. work and personal.
heroku plugins:install git://github.com/ddollar/heroku-accounts.git
Then set up each account:
heroku accounts:add personal --auto
heroku accounts:add work --auto
Set your default:
heroku accounts:default personal
Then to switch account for an app:
heroku accounts:set work
It’s generally good practise to pass variables to view partials using locals rather than littering your code with
This allows better reuse of the partial.
To make the locals optional, provide default values if they are
nil or undefined. I have seen many recommendations to do this with a test for
According to the rails api this will not work and
local_assigns.has_key? should be used.
My preference is to use
With 2 caveats:
- If the default value is
falsethe right hand side of the expression will always be evaluated. I can live with this as I think the any effect on performance will be insignificant.
- The second caveat is when the default is
true. The above statement would convert a local passed in as
truewhich is obviously not the intent. Instead, for default values of
true, this should be used.
Create the app
- If not installed, install PostgreSQL
rails new app_name -T -d=postgresql
rvm --create --rvmrc 1.9.2@app_name
rvm rvmrc trust
- Edit .Gemfile
createuser -P -S -R -d app_name(no to ‘Superuser’ and ‘Create roles’, yes to ‘Create databases’)
- Create procfile in app root.
foreman startand check http://0.0.0.0:5000/
Push to Github
- Edit .gitignore
git flow init
git add .
git commit -m 'Project skeleton'
- Create app_name on Github
git remote add origin email@example.com:JohnPlummer/app_name.git
git push -u origin develop
git push -u origin master
Push to Heroku
heroku create app-name --stack cedar
git flow release start '0.0.1'
git flow release finish '0.0.1'
git push --all
git push heroku master
heroku run rake db:seed
The default database for Heroku is PostgreSQL and, while you could use SQLite for development and Postgres for production, there are some inconsistencies between the two. Ideally you would use the same version of the database server but currently Heroku uses version 9 for dedicated databases and 8.3 for shared databases and seem to recommend you install the latest version for development.
Install Postgres with Homebrew with
brew install postgresql and follow the instructions after the install to initialise a database.
The database server can be set to start at login with
mkdir -p ~/Library/LaunchAgents
cp /usr/local/Cellar/postgresql/9.1.1/org.postgresql.postgres.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/org.postgresql.postgres.plist
But I prefer to add aliases to .bashrc to start and stop the server:
alias pgs='pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start'
alias pgq='pg_ctl -D /usr/local/var/postgres stop -s -m fast'
Postgres can be managed with the command line utility psql but, as much as I like the command line, I don’t really want to have to write SQL to edit or remove a user role. PgAdmin is a free GUI for Postgres management. Once installed, ensure the Postgres server is running then run pgAdmin and connect to the server.
In the server properties add a name for the connection and add your login as the username.
pgAdmin provides the management tools you would expect.
I realise that OSX does not have a registry to clog up but I have just reinstalled Lion on my Macbook Air; probably a hang up from Windows. This is a checklist for installing Homebrew >> Rails.
- Install XCode 4.1 (There are issues with the 4.2 compiler and certain rubies and gems)
- Install Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"
- Ensure Homebrew apps are in path before Mac apps
export PATH=/usr/local/bin:$PATHor edit /etc/paths
- Install Git
brew install git(thanks Brendan)
- Install SSH keys
- Generate or copy from ~/.ssh from a backup.
- Install RVM
bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.to bash_profile
- Restart shell
rvm | head -1
- Install latest Ruby and set as default
rvm install 1.9.3(make sure you are using Xcode 4.1)
rvm --default use 1.9.3
- Install Rails
gem install rails
I keep all my .config files in Dropbox and run a bash script to create aliases in my home folder.
Lion introduces some new gestures which unfortunately breaks some gestures I am used to such as a three finger swipe to move back in Chrome. Easily fixed by opening System Preferences > Trackpad > More Gestures and changing swipe between full screen apps to use four fingers and swipe between pages to use three.