Skip to content

Instantly share code, notes, and snippets.

@quachngocxuan
Last active February 7, 2018 08:59
Show Gist options
  • Save quachngocxuan/b61a02e4a55f8f60c69e351aaa518f86 to your computer and use it in GitHub Desktop.
Save quachngocxuan/b61a02e4a55f8f60c69e351aaa518f86 to your computer and use it in GitHub Desktop.
Learn enough to be dangerous - Rails

Learn enough to be dangerous - Rails

INTRODUCTION

The Rails philosophy includes two major guiding principles:

  • Don't Repeat Yourself: DRY
  • Convention Over Configuration

Rails is packed with features that make you more productive, with many of the following features building on one other.

  • Metaprogramming
  • Active Record
  • Convention over configuration
  • Scaffolding
  • Built-in testing
  • Three environments

Rails creates a fresh copy of the Test database for each test run.

Rails applications are structured around the model-view-controller (MVC) software engineering pattern.

Rails uses a template system called Embedded Ruby (ERB) by default.

SCAFFOLDING

Generate new Rails app

Go to the app folder and run

$ rails new .

Or to specify what kind of database and what kind of source code management system your application is going to use.

$ rails new . --git --database=postgresql

Generate a resource skeleton

Ex: generate 'Post' resource with two fields: title and body

$ rails generate scaffold Post title:string body:text

This command should create a table named posts with fields named id, title, body, created_at, and updated_at.

Or only generate a model for the resource

$ rails generate model Comment commenter:string body:text post:references

Destroy resource

Replace 'generate' by 'destroy', like this

$ rails destroy controller lalala
$ rails destroy model yadayada
$ rails destroy scaffold hohoho

Templating framework

The default one is ERB. But someones prefer HAML.

RAILS COMMANDS

gem command

The gem command installs Ruby gems. The Rails framework is actually distributed as a collection of gem files. Your newly created Rails application is made up of over 40 gems. Main taining the correct versions of these gems and dependencies between them can get complicated. For this reason, you rarely use the gem command directly; instead, you usually rely on a tool called Bundler to manage gems and keep your dependencies up to date.

bundle command

The bundle command is used to install and update the gems needed by your application. It installs gems by reading the Gemfile that was automatically created by the rails new command in the root directory of your Rails application. It stores the version numbers of gems you’re using and their dependencies in the file Gemfile.lock.

To displays the names and versions of all gems currently being used by your application

$ bin/bundle list

rails command

This command do many task depending on options

Open IRB

$ bin/rails console

Run internal server

$ rails server

or run on cloud9

$ rails server -b $IP -p $PORT

Migrate DB

$ rails db:migrate

Routing

Change in config/routes.rb

Route homepage to an action

Rails.application.routes.draw do
  #...
  root 'tasks#index'
end

COMMON TASKS

Seeding database

See details in this guide

With the file db/seeds.rb, the Rails gods have given us a way of feeding default values easily and quickly to a fresh installation. This is a normal Ruby program within the Rails environment.

Write your default data in this file like this

tasks = Task.create([{title: 'First task', note: 'N/A'}])

And run this command to seed data

$ rails db:seed

Migrate DB with some change on fields

  1. Migrate by hand

Create a migration to add new column

$ rails g migration AddUserNameToUsers user_name:string
  1. Migrate by gem For example, we want to add new upload field in the model
has_attached_file :image

To make this change reflect on DB, it should do migrate on the resource (here is post) by paperclip gem generated???

$ rails g paperclip post image

Ref more on this guide: https://www.devwalks.com/lets-build-instagram-in-rails-part-1/

Add new gem to Gemfile

After adding new gem to Gemfile, we have to bundle the app again

$ bundle update
$ bundle install --without production

Implement social login with devise gem

Ref: https://github.com/zquestz/omniauth-google-oauth2 Source: https://bitbucket.org/xuan_quach/rails_instagram

  1. Setup a cridential in google console and enable Google+ API. The callback URL is like this: http://ror2017-blank-xuan-quach.c9users.io/users/auth/google_oauth2/callback

  2. Setup gem

gem "omniauth-google-oauth2"
gem 'devise'

and run

$ bundle install
  1. Add to routes.rb
devise_for :users, :controllers => { registrations: 'registrations', :omniauth_callbacks => "users/omniauth_callbacks" }
  1. Define your application id and secret in config/initializers/devise.rb
config.omniauth :google_oauth2, 'GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET', {}
  1. Then add the following to 'config/routes.rb' so the callback routes are defined.
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
  1. Make sure your model is omniauthable. Generally this is "/app/models/user.rb"
devise :omniauthable, omniauth_providers: [:google_oauth2]
  1. Then make sure your callbacks controller is setup on file /app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google_oauth2
      # You need to implement the method below in your model (e.g. app/models/user.rb)
      @user = User.from_omniauth(request.env['omniauth.auth'])

      if @user.persisted?
        flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
        sign_in_and_redirect @user, event: :authentication
      else
        session['devise.google_data'] = request.env['omniauth.auth'].except(:extra) # Removing extra as it can overflow some session stores
        redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n")
      end
  end
end
  1. And bind to or create the user on the model /app/models/user.rb
def self.from_omniauth(access_token)
    data = access_token.info
    user = User.where(email: data['email']).first

    # Uncomment the section below if you want users to be created if they don't exist
    # unless user
    #     user = User.create(name: data['name'],
    #        email: data['email'],
    #        password: Devise.friendly_token[0,20]
    #     )
    # end
    user
end
  1. For your views you can login using:
<%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path %>

<%# Devise prior 4.1.0: %>
<%= link_to "Sign in with Google", user_omniauth_authorize_path(:google_oauth2) %>

Deploy on heroku

  1. Firstly, we have to make a our project as a git repo

  2. Change Gemfile to make it can be deployed on heroku. Change production to use a proper database (ex: postgres) like this:

source 'https://rubygems.org'

gem 'rails',        '5.1.2'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.7.0'

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.0.8'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

group :production do
  gem 'pg', '0.20.0'
end
  1. Create heroku app (choose an available app name)
$ heroku create rubyonrails-toy-app
$ git push heroku master
  1. Migrate DB
$ heroku run rails db:migrate
  1. Seeding DB If we have seed for our DB (defined in db/seed.rb), tell heroku to run it
$ heroku run rails db:seed
  1. Update change If any change in Gemfile, we should bundle it first
$ bundle update

When we update code, we have to push it to git before deploy again on heroku

$ git commit -am 'Comment'
$ git push
$ git push heroku master
$ heroku run rails db:migrate   # if having any change in DB. May be the same: $ heroku run 'rake db:setup'

Deploy app with clearDB on Heroku

  1. Setup db add-on on Heroku (ex: clearDB) Follow this guide. After setup, we can get connection's URL by this command:
$ heroku config | grep CLEARDB_DATABASE_URL
  1. Update Gemfile Set gem for mysql
group :production do
  gem 'mysql2'
end
  1. Update DB server connection in db/database.yml like this
production:
  url: 'mysql2://bfc84836d2a658:a3e0f49d@us-cdbr-iron-east-05.cleardb.net/heroku_ff0a8b9a8b6a9f9?reconnect=true'

For security reason, it's better to setup heroku environment variable for this connection's URL, follow this guide.

  1. Bundle rails app
$ bundle update
  1. Commit to git
$ git commit -am 'Comment'
$ git push
  1. Commit to heroku
$ git push heroku master
  1. Setup DB on heroku
$ heroku run 'rake db:setup'

Integrate Bootstrap into Rails

Ref: https://launchschool.com/blog/integrating-rails-and-bootstrap-part-1

  1. Add bootstrap gem in Gemfile
gem 'bootstrap-sass', '~> 3.2.0'
  1. Bundle it
$ bundle install
  1. Create CSS proprocessor file There're 3 CSS preprocessor types (LESS, SASS, SCSS), change css file to a preprocessor file depending on what type you choose.

Ex: I choose SCSS (similar to CSS), so rename app/assets/stylesheets/application.css to app/assets/stylesheets/application.css.sass Then import the Bootstrap assets in your newly renamed file

// app/assets/stylesheets/application.css.sass
...
@import "bootstrap-sprockets"
@import "bootstrap"
  1. Import Bootstrap Javascript assets You need to add:
//= require bootstrap-sprockets

into your app/assets/javascripts/application.js file. It is important that it comes after:

//= require jquery

Your file should look like this:

// app/assets/javascripts/application.js

...

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

It is also important that:

//= require_tree .

is the last thing to be required.

REFERENCES

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