Skip to content

Instantly share code, notes, and snippets.

@Papillard
Last active December 1, 2021 02:07
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Papillard/515c32d223ff55edffab to your computer and use it in GitHub Desktop.
Save Papillard/515c32d223ff55edffab to your computer and use it in GitHub Desktop.
Kick-off cheat sheet to set your Rails app @lewagon

This is a kick-off roadmap for the lead-developer, in charge of setup / deployment / collaboration.

Rails new

Create the project locally and on Github

$ rails new YOUR_APP_NAME -T --database=postgresql
$ cd YOUR_APP_NAME
$ git init
$ git add .
$ git commit -m "rails new"
$ hub create
$ git push -u origin master

Make sure you have the relevant ruby and rails version set in the Gemfile

# Gemfile
source 'https://rubygems.org'
ruby "2.2.0"
gem 'rails', '4.2.0'

Commit

$ git add .
$ git commit -m "setting ruby and rails versions"

Create the db locally

$ rake db:create

Development gems

Add debug gems

# Gemfile
group :development do
  gem "better_errors"
  gem "binding_of_caller"
  gem "quiet_assets"
  gem "pry-rails"
  gem "pry-byebug"
end

and commit

$ bundle install
$ git add .
$ git commit -m "Adding development gems"

Front-end setup

Add front-end gems

# Gemfile
gem 'bootstrap-sass'
gem 'font-awesome-sass'
gem 'simple_form'

Generate simple form Bootstrap 3 initializer

$ bundle install
$ rails generate simple_form:install --bootstrap

Add Bootstrap sprockets directive in application.js

// app/assets/javascripts/application.js

//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require_tree .

Add viewport in layout application.html.erb

<!-- app/views/layouts/application.html.erb -->
<head>
  <!-- Add these line for detecting device width -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>

Add dynamic meta tags in your layout

<!-- app/views/layouts/application.html.erb -->
<head>
  <title><%= yield(:title) || "Your App name" %></title>
  <meta name="description" content="<%= (yield(:description) || "").squish %>">
  <!-- [...] -->
</head>

Switch javascript application tag at the end of the body and set an :after_js block of code for page-specific javascript code

<!-- app/views/layouts/application.html.erb -->
<body>
  <!-- [...] -->

  <%= javascript_include_tag 'application' %>
  <%= yield(:after_js) %>
</body>

Load our custom LeWagon's stylesheets:

$ rm -rf app/assets/stylesheets
$ curl -L https://github.com/lewagon/rails-stylesheets/archive/master.zip > app/assets/stylesheets.zip
$ cd app/assets && unzip stylesheets.zip && rm stylesheets.zip && mv stylesheets-master stylesheets && cd ../..

And commit

$ git add .
$ git commit -m "Finishing front-end setup"

Figaro

Make figaro install on master branch (to avoid leaks of API keys in application.yml!!)

# Gemfile
gem "figaro"

Then add application.yml in .gitignore

$ bundle install
$ figaro install
$ git add .
$ git commit -m "setting figaro on master branch"

Github

Push your setup on Github

$ git push origin master

Then add your team-mates as collaborators and make them clone the repo!

Heroku

# Gemfile
gem 'rails_12factor', group: :production
gem 'puma',           group: :production
$ bundle install
$ curl -L https://gist.github.com/ssaunier/24bc1c4db955c19e3289/raw/install.sh | bash
$ git add .
$ git commit -m "Prepared for Heroku"
$ heroku create YOUR_APP_NAME --region eu
$ git push heroku master

Devise

# Gemfile
gem 'devise'
$ bundle install
$ rails generate devise:install
# config/initializers/devise.rb

# ==> Mailer Configuration
config.mailer_sender = 'contact@yourcompany.com'

Generate user model

$ rails generate devise User
$ rake db:migrate

Get a cool navbar and notices

<!-- app/views/layouts/application.html.erb -->
<%= render 'shared/navbar' %>
<%= render 'shared/notices' %>
<%= yield %>

Create shared/_navbar.html.erb with our template

And add shared/_notices.html.erb with Bootstrap alerts

<!-- app/views/shared/_notices.html.erb -->
<% if notice %>
  <div class="alert alert-info alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <%= notice %>
  </div>
<% end %>
<% if alert %>
  <div class="alert alert-warning alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <%= alert %>
  </div>
<% end %>

Customize devise views:

$ rails g devise:views
<!-- app/views/devise/registrations/new.html.erb -->
<div class="container">
  <div class="row">
    <div class="col-sm-6 col-sm-offset-3">
      <h2>Sign up</h2>
      <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
        <%= f.error_notification %>

        <%= f.input :email, required: true, autofocus: true %>
        <%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable) %>
        <%= f.input :password_confirmation, required: true %>
        <%= f.button :submit, "Sign up", class: "btn btn-primary" %>
      <% end %>

      <%= render "devise/shared/links" %>
    </div>
  </div>
</div>
<!-- app/views/devise/sessions/new.html.erb -->
<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-6 col-sm-offset-3">
      <h2>Log in</h2>

      <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
          <%= f.input :email, required: false, autofocus: true %>
          <%= f.input :password, required: false %>
          <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
          <%= f.button :submit, "Log in", class: "btn btn-primary" %>
      <% end %>

      <%= render "devise/shared/links" %>
    </div>
  </div>
</div>

Force login on your app controller

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
end

And commit your work

$ git add .
$ git commit -m "Finish devise integration"

Facebook-connect

# Gemfile
gem 'omniauth-facebook'
$ bundle install
$ figaro install

Create you facebook app and set your development keys in application.yml

development:
  FB_ID: "3************1"
  FB_SECRET: "4************e"

Configure devise

# config/initializers/devise.rb

Devise.setup do |config|
  config.omniauth :facebook, ENV["FB_ID"], ENV["FB_SECRET"], scope: 'email'
end

Change your devise routing to handle omniauth callbacks

# config/routes.rb
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }

Change User model

# app/models/user.rb

class User < ActiveRecord::Base
  devise :omniauthable, :omniauth_providers => [ :facebook ]
end

Add facebook fields to users table

$ rails g migration AddOmniauthToUsers provider uid picture name token token_expiry:datetime
$ rake db:migrate

And set a method on the User model to record these fields from facebook callbacks

class User < ActiveRecord::Base
  def self.find_for_facebook_oauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]  # Fake password for validation
      user.name = auth.info.name
      user.picture = auth.info.image
      user.token = auth.credentials.token
      user.token_expiry = Time.at(auth.credentials.expires_at)
    end
  end
end

Integrate this in your callbacks controller

# app/controllers/users/omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    user = User.find_for_facebook_oauth(request.env["omniauth.auth"])

    if user.persisted?
      sign_in_and_redirect user, event: :authentication
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
end

Change a bit your navbar code

<!-- Somewhere in your navbar -->
<!-- Regular login -->
<li>
  <%= link_to "Connexion", new_user_session_path %>
</li>
<!-- Facebook login -->
<li>
  <%= link_to "Connect with Facebook", user_omniauth_authorize_path(:facebook) %>
</li>

And insert your facebook profile in navbar

<!-- Somewhere in your navbar -->
<% if user_signed_in? %>
  <%= image_tag current_user.picture, class: "img-avatar" %>
<% end %>

Commit your work:

$ git add .
$ git commit -m "adding fb connect"

When pushing on heroku, run the migrations and set the API keys of your production FB app on Heroku

$ git push heroku master
$ heroku run rake db:migrate
$ heroku config:set FB_ID=************ FB_SECRET=*********
@ssaunier
Copy link

ça mériterait un lewagon/rails-kickoff plutot qu'un gist ;)

@cveneziani
Copy link

+1 :)

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