Skip to content

Instantly share code, notes, and snippets.

@peterkappus
Last active November 20, 2016 13:17
Show Gist options
  • Save peterkappus/ccf7726eb78f33e323f8022463d3ee17 to your computer and use it in GitHub Desktop.
Save peterkappus/ccf7726eb78f33e323f8022463d3ee17 to your computer and use it in GitHub Desktop.
How I've been making rails apps in 2016

How I make rails apps in 2016

This is a quick step-by-step guide for how I've been getting quick proof-of-concept rails apps up and running in 2016. Mostly for my own reference. Feedback welcome :)

Run it on Heroku

It’s just easier... Who needs to mess with devops in 2016?

  • Create an account at heroku.com
  • Install the Heroku command line tools on your machine

Get your machine ready

  • Install Ruby (with Rbenv?)
  • Install rails (with brew? or just gem install rails?) ... I can't remember
  • Install postgress brew install postgres

Store your code on github

Your stuff is open source right? No? Why not?

  • Visit github.com, login, and make a new repo.
  • Select the Rails .gitignore template
  • Return to your local machine and clone the repo into a folder there.
  • Clone it locally and setup rails
git clone [git_repo_url]
#use postgres for Heroku
rails new [git_repo_name] --database=postgresql

#create a new heroku app from here
heroku create [app_name]

Add a few gems

#so you can use "heroku local"
gem 'puma'

# use slim. Kuz.
gem "slim-rails"

  • Edit your .gitignore file to include your "secrets" (heroku needs these)
#config/initializers/secret_token.rb
#config/secrets.yml
  • Add the files, commit, and push
#commit the files and the Gemfile.lock so we can deploy to heroku
git commit -am "first commit"
git push

Deploy it

  • Go back to heroku and open your app (maybe star it for convenient access)

  • Click “Deploy" and click the “GitHub” button

  • Connect to Github, find your repo and connect it to your app

  • Click automatic deploys if you want this.

  • Back to your code, update your config/database.yml like so:

default: &default
  adapter: postgresql
  pool: 5
  encoding: unicode
  timeout: 5000

development:
  <<: *default
  database: infoshare_dev

test: &test
  <<: *default
  database: infoshare_test

cucumber:
  <<: *test

Run it locally

Make sure the database is running

#see how to start it (if you installed via brew)
brew info postgres
#Run whatever command the above recommends for your needs (e.g. run backround process or just keep it open in a shell)

#setup the databse
rake db:setup
rake db:migrate

Re-run bundler:
`bundle`

Create a Procfile that looks like this:

web: bundle exec puma -t 5:5 -p ${PORT:-3000} -e ${RACK_ENV:-development}

Start herou locally

heroku local

What's next?

  • Write some tests, create some models, migrate your database, create some views, commit re-deploy... rinse and repeat.

REMEMBER TO heroku run rake db:migrate when you need to migrate...

Heroku won't do this for you automagically

Testing with Cucumber

NOT FINISHED Add this to your Gemfile

#cucumber stuff
gem 'cucumber' #our testing framework
gem 'capybara' #nice DSL for talking to the browser in code.
gem 'selenium-webdriver' #usual, firefox driver
gem 'phantomjs'
gem 'poltergeist' #headless driver
gem 'rspec' #gives us a few nice methods like "page.should"
gem 'pry' # for command line debugging
gem 'capybara-screenshot'
gem 'firefox'
gem 'cucumber-rails', :require => false
# database_cleaner is not required, but highly recommended
gem ‘database_cleaner'

Wanna use the GOV.UK fronted?

Add these gems to your Gemfile

#for GOV.UK template
gem 'govuk_template'
#gem 'slimmer'

#for other GOV.UK elements
gem 'govuk_elements_rails'

#for sass mixins
gem 'govuk_frontend_toolkit'

You'll need to make a layouts/application.html.slim file. See here.

Oauth Authentication

  • Register your app on the Google console (if that's what you're using)
  • Get your client ID and secret
  • use a .env file to hold these in environment variables
  • Create a sessions controller with methods for new (basically redirects to the /auth URL), create (handles the callback), destroy (logs out),
  • Create "signed_in?" method in application_controller.rb
  • Add this, before_filter :check_login, :except=>[:welcome, :about] to allow non-logged in folk to see the welcome & about pages.
  • Add the "check_login" method..

Make it more robust:

  • Add a User model to hold name, email, is_admin? flag, etc.
  • Add a user controller to perform CRUD operations on Users

##Troubleshooting

Heroku complaining about secret keys?

Make sure you’ve committed your secrets.yml file (check you .gitignore)

/https://github.com/alphagov/govuk_template/blob/master/source/views/layouts/govuk_template.html.erb
- content_for :head do
=javascript_include_tag "application.js"
= csrf_meta_tags
style
| main { max-width: 960px; margin: 0 15px; }
| @media (min-width: 641px) { main { margin: 0 30px; } }
| @media (min-width: 1020px) { main { margin: 0 auto; } }
= stylesheet_link_tag "application", media: :all
- content_for :page_title do
| GDS Goals
- content_for :inside_header do
- if signed_in?
form#search.site-search method="get" action="#{search_goals_path}"
.content
/label for="site-search-text" Search the service manual
input#site-search-text.js-search-focus type="search" name="q" title="Search" role="search" placeholder="Search"
input.submit type="submit" value="Search"
- content_for :header_class do
| with-proposition
- content_for :proposition_header do
.header-proposition.noprint
.content
a href='#proposition-links' class='js-header-toggle menu' Menu
nav#proposition-menu
=link_to "GDS Goals", root_path, :id=>"proposition-name"
- if (signed_in?)
ul#proposition-links
/li =link_to "Home", goals_path
/li =link_to "Groups and Teams", groups_path
/li = link_to "SDP goals", sdp_goals_path
/li =link_to "Teams", teams_path
/li =link_to "About", about_path
-if is_admin?
li =link_to "Manage users", users_path
- content_for :body_end
- if(ENV['GOOGLE_ANALYTICS_ID'].present?)
javascript:
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '#{ENV['GOOGLE_ANALYTICS_ID']}', 'auto');
ga('send', 'pageview');
- content_for :content do
#wrapper
main#content[role="main"]
-if (ENV['IS_SANDBOX'] || Rails.env.development?)
.noprint style="background: #fc0; text-align: center; font-size: 3rem" This is a playground environment. Tweak with impunity.
.row
.col-sm-12
.phase-banner-alpha.noprint
p
strong.phase-tag PRE-ALPHA
span This is a proof of concept only. Goals are in DRAFT. Your <a href="https://docs.google.com/document/d/1oR76UEjYT0DWFPk0wZVDaJxtAy5UevM2mIvoNmcZDCw/edit" target="_blank">feedback</a> will help us to improve.
- if signed_in?
.row.account_info.noprint
.col-md-12
.pull-right
span #{link_to current_user.name, current_user}: #{link_to 'Sign out', signout_path}
.inner-block
- flash.each do |name, msg|
= content_tag :div, class: "alert alert-#{ name == "error" ? "danger" : "success" } alert-dismissable", role: "alert" do
button.close type="button" data-dismiss="alert"
span aria-hidden="true"
| &times;
span.sr-only
| Close
= msg
/ Redirecting automatically from application controller so no one will ever see this...
- if request.host.match(/gdsdash.heroku/) then
.alert.alert-warning
h2 NOTE: This site has moved to <a href="http://gdsdelivery.herokuapp.com">http://gdsdelivery.herokuapp.com</a>. Please update your bookmarks.
= yield
- content_for :footer_top do
main
.row
-if signed_in?
.col-sm-6
b Download data
ul
li = link_to "Download goals (CSV)", goals_path(:format=>:csv)
li = link_to "Download status updates (CSV)", scores_path(:format=>:csv)
- if (Rails.env.development? && User.where(admin: true).count > 0 && User.where(admin: nil).count > 0)
.col-sm-6
b Development tools
ul
li =link_to "Sign in as admin", signin_path(email: User.where(admin: true).first.email)
li =link_to "Sign in as non-admin", signin_path(email: User.where(admin: nil).first.email)
= render template: "layouts/govuk_template"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment