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.
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
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
Replace 'generate' by 'destroy', like this
$ rails destroy controller lalala
$ rails destroy model yadayada
$ rails destroy scaffold hohoho
The default one is ERB. But someones prefer HAML.
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.
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
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
Change in config/routes.rb
Route homepage to an action
Rails.application.routes.draw do
#...
root 'tasks#index'
end
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 by hand
Create a migration to add new column
$ rails g migration AddUserNameToUsers user_name:string
- 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/
After adding new gem to Gemfile
, we have to bundle the app again
$ bundle update
$ bundle install --without production
Ref: https://github.com/zquestz/omniauth-google-oauth2 Source: https://bitbucket.org/xuan_quach/rails_instagram
-
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
-
Setup gem
gem "omniauth-google-oauth2"
gem 'devise'
and run
$ bundle install
- Add to routes.rb
devise_for :users, :controllers => { registrations: 'registrations', :omniauth_callbacks => "users/omniauth_callbacks" }
- Define your application id and secret in config/initializers/devise.rb
config.omniauth :google_oauth2, 'GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET', {}
- Then add the following to 'config/routes.rb' so the callback routes are defined.
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
- Make sure your model is omniauthable. Generally this is "/app/models/user.rb"
devise :omniauthable, omniauth_providers: [:google_oauth2]
- 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
- 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
- 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) %>
-
Firstly, we have to make a our project as a git repo
-
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
- Create heroku app (choose an available app name)
$ heroku create rubyonrails-toy-app
$ git push heroku master
- Migrate DB
$ heroku run rails db:migrate
- Seeding DB
If we have seed for our DB (defined in
db/seed.rb
), tell heroku to run it
$ heroku run rails db:seed
- 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'
- 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
- Update Gemfile Set gem for mysql
group :production do
gem 'mysql2'
end
- 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.
- Bundle rails app
$ bundle update
- Commit to git
$ git commit -am 'Comment'
$ git push
- Commit to heroku
$ git push heroku master
- Setup DB on heroku
$ heroku run 'rake db:setup'
Ref: https://launchschool.com/blog/integrating-rails-and-bootstrap-part-1
- Add bootstrap gem in Gemfile
gem 'bootstrap-sass', '~> 3.2.0'
- Bundle it
$ bundle install
- 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"
- 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.