Ruby and rails - Advanced Training (Cybage)

Post on 27-Aug-2014

98 views 4 download

Tags:

description

Cybage Advanced Training - customised

Transcript of Ruby and rails - Advanced Training (Cybage)

Ruby and Rails Advanced Training

@gautamrege @joshsoftware

Agenda - Day 1Discuss Ruby basics

Syntax, classes, modules. Meta-programming. Closures

Rails concepts Discussion around Rails design patterns. ActiveSupport Concern Rails engines

Agenda - Day 2Discuss 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 Dataclass 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 Mixinsclass 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

endclass Base include Foo end

Dependent Modules

Dependent Modulesmodule Foo

def self.included(base)

base.class_eval do

def self.foo_method

end

end

end

end

Dependent Modulesmodule 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 Modulesmodule 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 Modulesmodule 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

endclass 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 - CarCreate 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-RocketCreate 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 Stuffrails 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

ChecklistAutomatic 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 CachingCache 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 PerformanceNewRelic Monitoring

Log file and debugging

Load Testing

Concurrency testing

Performance Benchmark using benchmark-ips

http://guides.rubyonrails.org/v3.2.13/performance_testing.html