Ruby and Rails
Advanced Training
@gautamrege
@joshsoftware
Agenda - Day 1
Discuss Ruby basics
Syntax, classes, modules.
Meta-programming.
Closures
Rails concepts
Discussion around Rails design
patterns.
ActiveSupport Concern
Rails engines
Agenda - Day 2
Discuss your current Applications.
Gems currently in use
Resolving problems.
ActiveResource
Rails Security
Data Caching
Performace monitoring and improvement
Ruby is easy, right?
Ruby is easy, right?
1 + 1
Ruby is easy, right?
1 + 1
1.+(1)
Ruby is easy, right?
1 + 1
1.+(1)
1.+ 1
Ruby is easy, right?
1 + 1
1.+(1)
1.+ 1
1.send(:+, 1)
How many objects?
How many objects?
1 + 2 + 3
How many objects?
1 + 2 + 3
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
How many objects?
1 + 2 + 3
( 1.+(2) ).+(3)
FIVE
objects
Everything in Ruby
is an object
on which we call a method
to which we pass parameters
and an optional block of code
So, you know Ruby?
So, you know Ruby?
a[1] # What is the data type of a?
So, you know Ruby?
a[1] # What is the data type of a?
a = [‘a’, ‘b’] # Array
So, you know Ruby?
a[1] # What is the data type of a?
a = [‘a’, ‘b’] # Array
a = { 1 => ‘a’} # Hash
So, you know Ruby?
a[1] # What is the data type of a?
a = [‘a’, ‘b’] # Array
a = { 1 => ‘a’} # Hash
a = “abc” # String
So, you know Ruby?
a[1] # What is the data type of a?
a = [‘a’, ‘b’] # Array
a = { 1 => ‘a’} # Hash
a = “abc” # String
a = Proc.new { | x | p x } # proc
Multiplication
Multiplication
[1, 2, 3] * 2
Multiplication
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
Multiplication
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
[1, 2, 3] * “%”
Multiplication
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
[1, 2, 3] * “%”
# => “1%2%3”
There’s always an
easier way
Summation of [1, 2, 3, 4]
Non-ruby way!
sum = 0
!
for i in [1, 2, 3, 4]
sum += i
end
!
p sum
The Amateur!
sum = 0
!
[1, 2, 3, 4].each do |i|
sum += i
end
!
p sum
The Professional!
!
[1, 2, 3, 4].inject(0) do |sum, i|
sum + i
end
The Expert!
!
[1, 2, 3, 4].inject(:+)
Exceptions… never!
class Base
def method_missing(name, *args, &blk)
puts “Unknown method #{name}
called.”
end
end
b = Base.new
b.wtf
What’s in a name?
# User(id: integer, name: string)
class User < ActiveRecord::Base
end
u = User.name
u.name
u.name = “Gautam”
Accessing Data
class User
def initialize
@name = “someone”
end
end u = User.name
u.name
u.name = “Gautam”
Protected & Private
Private methods are inherited
Protected method can be called on
another object in same lineage
What the …
Module Mixins
class Shaktiman
include Spiderman
include Superman
end
irb> Shaktiman.ancestors
=> [ Shaktiman, Superman, Spiderman …]
Closures
sum = 0
[1, 2, 3, 4].each do |x|
sum += i
end
p sum
Anonymous functions?
Local variables scope?
Closures
!
Context sensitive block of code
Rails Design
Patterns
Rails Design
Patterns
Singleton
Rails Design
Patterns
Singleton
Factory
Rails Design
Patterns
Singleton
Factory
Observer
Rails Design
Patterns
Singleton
Factory
Observer
…
Rails Design
Patterns
Singleton
Factory
Observer
…
You cannot learn
Design Patterns!
!
You need to experience
them
SOLID Design
Patterns
SOLID principles
S - Single Responsibilty
O - Open / Closed
L - Liskov Substituion
I - Interface Segregation
D - Dependency Inversion
Single
Responsibility
Serves only one purpose.
Models - manage data
Controllers - manage logic
No logic in views!
Open / Closed
Open for Extension
Closed for modification
Open / Closed
Open for Extension
Closed for modification
ParseFeed
Open / Closed
Open for Extension
Closed for modification
ParseFeed
Atom RSS
ParseFeed
Liskov Substituion
Functionality should work for all
derived classes.
Let q(x) be a property provable about
objects x of type T. Then q(y) should
be true for objects y of type S where
S is subtype of T
Interface
Segregation
Classification based on behaviour
Vehicle
AirRoad
TrainCar RocketAirplane
Dependency
Inversion
High level modules should not
depend on low level modules
Modules should depend on
abstractions
Details should depend on
abstractions
ActiveSupport
Concern
Without ActiveSupport
Concerns
module Foo
def self.included(base)
base.class_eval do
scope :disable, -> { where(disabled: true) }
end
end
end
class Base
include Foo
end
With ActiveSupport
Concerns
module Foo
extend ActiveSupport::Concern
included do
scope :disable, -> { where(disabled: true) }
end
end
class Base
include Foo
end
Dependent Modules
Dependent Modules
module Foo
def self.included(base)
base.class_eval do
def self.foo_method
end
end
end
end
Dependent Modules
module Foo
def self.included(base)
base.class_eval do
def self.foo_method
end
end
end
end
module Bar
def self.included(base)
base.foo_method
end
end
Dependent Modules
module Foo
def self.included(base)
base.class_eval do
def self.foo_method
end
end
end
end
module Bar
def self.included(base)
base.foo_method
end
end
class Base
include Foo
include Bar
end
Dependent Modules
module Foo
def self.included(base)
base.class_eval do
def self.foo_method
end
end
end
end
module Bar
def self.included(base)
base.foo_method
end
end
class Base
include Foo
include Bar
end
add module
dependency
#!!
Module
dependencies
Module
dependencies
module Bar
include Foo
included do
def self.foo_method
end
end
class Base
include Bar
end
Module
dependencies
module Bar
include Foo
included do
def self.foo_method
end
end
class Base
include Bar
end
self = Bar
self != Base
Module
dependencies
module Bar
include Foo
included do
def self.foo_method
end
end
class Base
include Bar
end
self = Bar
self != Base
Module
dependencies
module Bar
extend ActiveSupport::Concern
include Foo
included do
def self.foo_method
end
end
class Base
include Bar
end
no including
extra modues
self = Base
Rails Engines
Engine power
Velocity App
CarRocket
Some custom
Functionality
CarRocket
Some custom
functionality
CarRocket
Some custom
functionality
Astronaut
Shuttles
M
M
CarRocket
Some custom
functionality
Astronaut
Shuttles
M
M
Driver
Rto
M
1
CarRocket
Some custom
functionality
Astronaut
Shuttles
M
M
Driver
Rto
M
1
Company
Quick Reference
rails plugin new <name> —mountable
rails g scaffold <model> <name>:<type>
test/dummy: testing engine.
GamePlay - Car
Create Car engine
Create RTO scaffold
name:string code:string
Create Driver scaffold
name:string rto_id:integer
has_licence:boolean
Testing - Car
rake db:migrate
cd test/dummy
rails s
http://localhost:300/car
GamePlay-Rocket
Create Rocket engine
Create Astronaut scaffold
name:string degree:text
Create Shuttle scaffold
name:string launch_from:text
Create Space_flights scaffold
shuttle_id:integer astronaut_id:integer
launch_on:date
Testing - Rocket
rake db:migrate
cd test/dummy
rails s
http://localhost:3000/rocket
Application Stuff
rails new velocity
update Gemfile
gem ‘car’, path: <path>
gem ‘rocket’, path: <path>
config/routes:
mount Car::Engine, at: ‘/car’
mount Rocket::Engine, at: ‘/engine’
Application Logic
Company scaffold
name:string make_cars:boolean
make_rockets:boolean
owner:string
Using Application
models in engines.
Add migration for owner_id
class Shuttle
belongs_to :owner, class: “Company”
end
NEVER hardcode associations directly
in engines. Use class option.
More ???
Devise
Authentication
Gemfile
gem ‘devise’
rails g devise:install
rails g device user
rake db:migrate
Inherit from App
# rocket/app/controller/rocket/application_controller.rb
class Rocket::ApplicationController <
ApplicationController
end
# shuttles_controller.rb
class ShuttleController < ApplicationControler
before_action :authenticate_user!
end
Checklist
Automatic namespace resolution.
Views that access models require to be fully
resolved.
rake <engine>:install:migrations
rake railties:install:migrations
Controllers permit parameters
No hardcoded associations from top-level app.
Discussions!
ActiveResource
Rails Security
Caching
Performance
Q & A
ActiveResource
Rails Security
Authenticity Token
Protect from forgery
CSRF
SQL injection
XSS - html_safe & raw
http://guides.rubyonrails.org/security.html
Rails Caching
Cache Store:
memory, file, memcached, ehcache, custom
Page & Action caching (DEPRECATED)
http://signalvnoise.com/posts/3113-how-key-based-
cache-expiration-works
Fragment caching
Query caching
http://guides.rubyonrails.org/caching_with_rails.html
Rails Performance
NewRelic Monitoring
Log file and debugging
Load Testing
Concurrency testing
Performance Benchmark using benchmark-ips
http://guides.rubyonrails.org/v3.2.13/
performance_testing.html

Ruby and rails - Advanced Training (Cybage)