This is a kick-off roadmap for the lead-developer, in charge of setup / deployment / collaboration.
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
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"
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"
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"
Push your setup on Github
$ git push origin master
Then add your team-mates as collaborators and make them clone the repo!
# 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
# Gemfile
gem 'devise'
$ bundle install
$ rails generate devise:install
# config/initializers/devise.rb
# ==> Mailer Configuration
config.mailer_sender = '[email protected]'
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">×</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">×</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"
# 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=*********
ça mériterait un
lewagon/rails-kickoff
plutot qu'un gist ;)