SlideShare a Scribd company logo
Um roadmap do
Framework Ruby on Rails
do Rails 1 ao Rails 4
João Lucas Pereira de Santana
Apresentação
João Lucas Pereira de Santana
twitter | github | fb | gtalk: @jlucasps
Ciência da Computação pela UFLA
Desenvolvedor Ruby, Java, JavaScript
Instrutor Ruby on Rails

@jlucasps

#devday2013
Agenda
➔ Rails Full Stack - Request/Responder
➔ Primeira versão
◆ Active Support, Active Record, Action Pack, Action
Mailer

➔ Rails 2
➔ Rails 3
➔ Rails 4

@jlucasps

#devday2013
Rails Full Stack
➔ Origem
◆ David Heinemeier Hansson

@jlucasps

#devday2013
Rails Full Stack
➔ Rails Core Team

Jeremy Kemper

Michael Koziarski

Yehuda Katz

José Valim

Santiago Pastorino

Aaron Patterson

Xavier Noria

Jon Leighton

Rafael França

Andrew White

Guillermo Iguaran

Carlos Antonio

@jlucasps

#devday2013
Rails Full Stack
➔ Framework MVC para desenvolvimento Web

Session

Helpers

Logs

Testes

Middleware

Controller

Connections

Validations
Queries
Callbacks
Migrations

@jlucasps

Responders

Routes

Renders

Assets

Associations

Testes

HTTP/SSL

Helpers

Model

View

Builders

Testes

Templates
Partials

#devday2013
Rails Full Stack

request
Web Server
App Server

Rails

Controller

Model

View

response

@jlucasps

#devday2013
Rails Full Stack

REQUEST:
GET http://myapp.com/users/2/lists
ACCEPTED: passado para o App Server

Web Server
App Server

Request passado para o Rails

Rails

Controller

Model

@jlucasps

View

#devday2013
Rails Full Stack

Rails

Router
Controller

Model

@jlucasps

View

#devday2013
Rails Full Stack
Router
user_lists GET

/users/:user_id/lists(.:format)

lists#index

Controller e Action selecionadas:
GET /users/2/lists
CONTROLLER: "lists"
ACTION: "index"
NOME DA ROTA: "user_lists"
@jlucasps

#devday2013
Rails Full Stack
Controller

Rails

Router

index

new

create

update

Controller

Model

destroy

........

View

GET /users/2/lists
CONTROLLER: "lists"
ACTION: "index"
@jlucasps

ListsController

Model

View

#devday2013
Rails Full Stack
Model

@user = User.find(params[:user_id])
@lists = List.find_all_by_user_id(params[:user_id])

ListsController
index

new

User
Model

Active
Record

tabela 'users'

create
Banco de dados

update

@jlucasps

destroy

........

List
Model

Active
Record

tabela 'lists'

#devday2013
Rails Full Stack
REQUEST:
GET http://myapp.com/users/2/lists

ACCEPTED: passado para o App Server

Web Server

REQUEST passado para o Rails

App Server
Router

CONTROLLER recupera informações
dos MODELS para suprir a VIEW

Rails

PATH e METHOD mapeados para
CONTROLLER e ACTION

Controller
action

Model

@jlucasps

action

action

View

#devday2013
Rails Full Stack
View

Request Headers
Accept: text/html, application/xhtml+xml

ListsController
index

View
@vars

@vars

update

app/views/lists/index.html.erb

.html

.html

app/views/lists/update.html.erb

edit
..........
@jlucasps

#devday2013
Rails Full Stack
HTTP Response

@jlucasps

#devday2013
Rails Full Stack
REQUEST:
GET http://myapp.com/users/2/lists

ACCEPTED: passado para o App Server

Web Server

REQUEST passado para o Rails

App Server
Router

CONTROLLER recupera informações
dos MODELS para suprir a VIEW
VIEW cria a resposta para o RESPONSE
BODY

@jlucasps

Rails

PATH e METHOD mapeados para
CONTROLLER e ACTION

Controller
action

Model

action

action

View

#devday2013
Rails Full Stack
RESPONSE recebida :-)

RESPONSE é retornada para o browser

Web Server

RESPONSE volta através do middleware
stack

App Server

Rails

Router

VIEW cria a resposta para o RESPONSE
BODY

@jlucasps

Controller
action

Model

action

action

View

#devday2013
Rails Full Stack
Response

@jlucasps

#devday2013
rails-0.10.0
➔ Inflectors
SingularToPlural = {
"search"
=> "searches",
"category" => "categories",
"wife"
=> "wives",
"series"
=> "series"
}
CamelToUnderscore = {
"Product"
=> "product",
"SpecialGuest"
=> "special_guest"
}
CamelWithModuleToUnderscoreWithSlash = {
"Admin::Product" => "admin/product",
"UsersSection::CommissionDepartment" => "users_section/commission_department"
}
ClassNameToForeignKeyWithUnderscore = {
"Person" => "person_id",
"MyApplication::Billing::Account" => "account_id"
}
ClassNameToTableName = {
"PrimarySpokesman" => "primary_spokesmen",
"NodeChild"
=> "node_children"
}
@jlucasps

#devday2013
rails-0.10.0
➔ Breakpoints
[0, 9] in
/media/truecrypt1/rails4chat/app/controllers/pages_controller.rb
1 class PagesController < ApplicationController
2
3 def index
4
debugger
=> 5
@messages = Message.limit(20)
6 end
7
8 end
(rdb:1) params
{"controller"=>"pages", "action"=>"index"}
(rdb:1)

@jlucasps

#devday2013
rails-0.10.0
➔ active_support core_ext
◆ Time
# Calculations
assert_equal Time.local(2006,2,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year
=> 2006)
assert_equal Time.local(2005,2,22,10,10,9), Time.local(2005,2,22,10,10,10).ago(1)
assert_equal Time.local(2005,2,20,10,10,10), Time.local(2005,2,22,10,10,10).ago(86400*2)
assert_equal Time.local(2005,1,31), Time.local(2005,2,4,10,10,10).beginning_of_week
assert_equal Time.local(2005,2,4,0,0,0), Time.local(2005,2,4,10,10,10).beginning_of_day
# Conversions
assert_equal "February 21, 2005 17:44", Time.local(2005, 2, 21, 17, 44, 30).to_s(:long)
assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date
@jlucasps

#devday2013
rails-0.10.0
➔ active_support core_ext
◆ Numeric
# byte calculations
1024.kilobytes =>
1.kilobyte ** 4 =>

1.megabyte
1.terabyte

time calculations
1.minute

=> 60

1.hour + 15.minutes => 4500
2.days + 4.hours + 30.minutes => 189000

@jlucasps

#devday2013
rails-0.10.0
➔ active_support core_ext
◆ Hash

# hash
# stringify_keys, symbolize_keys e indifferent_access
strings = { 'a' => 1, 'b' => 2 }
symbols = { :a => 1, :b => 2 }
mixed

@jlucasps

= { :a => 1, 'b' => 2 }

#devday2013
rails-0.10.0
➔ active_support core_ext
◆ Date
# Getting dates in different convenient string representations and other
objects
assert_equal "21 Feb",

Date.new(2005, 2, 21).to_s(:short)

assert_equal "February 21, 2005", Date.new(2005, 2, 21).to_s(:long)

# to_time
assert_equal Time.local(2005, 2, 21), Date.new(2005, 2, 21).to_time

# to_date
assert_equal Date.new(2005, 2, 21), Date.new(2005, 2, 21).to_date
@jlucasps

#devday2013
rails-0.10.0
➔ active_record
◆ connections:
● db2, mysql, oracle, postgresql, sqlite, sqlite3,
sqlserver
◆ mapping:
table "products"
class Product < ActiveRecord::Base

end

@jlucasps

#devday2013
rails-0.10.0
➔ active_record
◆ associations:
class Firm < ActiveRecord::Base
has_many
has_one

:clients
:account

belongs_to :conglomorate
has_and_belongs_to_many :investors
end

# natural assignments:
apple.account = citibank
assert_equal apple.id, citibank.firm_id

@jlucasps

#devday2013
rails-0.10.0
➔ active_record
◆ validations:

# Validation rules that can differ for new or existing objects
class Account < ActiveRecord::Base
validates_presence_of

:subdomain, :name, :email_address, :

password
validates_uniqueness_of

:subdomain

validates_acceptance_of

:terms_of_service, :on => :create

validates_confirmation_of :password, :email_address, :on => :
create
end
@jlucasps

#devday2013
rails-0.10.0
➔ active_record
◆ callbacks:

# Callbacks as methods or queues on the entire lifecycle
# (instantiation, saving, destroying, validating, etc).
:after_find, :after_initialize, :before_validation
:before_validation_on_update, :after_validation
:after_validation_on_update, :before_save
:before_update, :after_update, :after_save
:before_destroy, :after_destroy

@jlucasps

#devday2013
rails-0.10.0
➔ active_record
◆ find and dynamic methods
# finds
Firm.find(1, 2)
Company.find_first "name = 'Next Angle'"
Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first
Topic.find(1, :conditions => "approved = 1")
Topic.find_by_title("The First Topic")
Topic.find_by_title_and_author_name("The First Topic", "David")
Topic.find_all_by_content("Have a nice day")
# dynamic methods
next_angle.clients.find(2)
next_angle.clients.empty?
next_angle.clients.size

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ action_controller:

BlogController < ActionController::Base
def show
@customer = find_customer
end

private
def find_customer() Customer.find(@params["id"]) end
end

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ filters:

class WeblogController < ActionController::Base
before_filter :authenticate, :cache, :audit
after_filter { |c| c.response.body = GZip::compress(c.response.body) }
end

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ layouts:

class WeblogController < ActionController::Base
layout "weblog_layout"
def hello_world

end
end

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ scaffold:

require 'account' # must be an Active Record class
class AccountController < ActionController::Base
scaffold :account

end
# templates: list, show, destroy, new, create, edit, update

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ advanced redirection

# Advanced redirection that makes pretty urls easy:
RewriteRule ^/library/books/([A-Z]+)([0-9]+)/([-_a-zA-Z0-9]+)$ 
/books_controller.cgi?action=$3&type=$1&code=$2 [QSA] [L]

# Accessing /library/books/ISBN/0743536703/show calls BooksController#show

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ action view:
<!-- Embedded Ruby for templates: -->
<% for post in @posts %>
Title: <%= post.title %>
<% end %>

<!-- Helpers for forms, dates, action links, and text: -->
<%= text_field "post", "title", "size" => 30 %>
<%= html_date_select(Date.today) %>
<%= link_to "New post", :controller => "post", :action => "new" %>
<%= truncate(post.title, 25) %>

@jlucasps

#devday2013
rails-0.10.0
➔ action_pack
◆ action view:

<!-- Form building for Active Record model objects: -->
<%= form "post" %>
<!-- This form generates a @params["post"] array that can be used directly in a
save action

<!-- Rendering shared partials: -->
<%= render_partial "advertisement/ad", ad %>

@jlucasps

#devday2013
rails-0.10.0
➔ action_mailer
def signed_up(recipient)
@recipients

= recipient

@subject

= "[Signed up] Welcome #{recipient}"

@from

= "system@loudthinking.com"

@sent_on

= Time.local(2004, 12, 12)

@body["recipient"] = recipient
end

ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the
email

@jlucasps

#devday2013
rails-0.11.0
➔ active_support
◆ string to date and time:
assert_equal Time.utc(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time
assert_equal Date.new(2005, 2, 27), "2005-02-27".to_date

➔ action_pack
◆ ajax

➔ action_mailer
◆ incoming mails
@jlucasps

#devday2013
rails-0.12.0
➔ Eager associations
➔ new Base.find API
➔ more Ajax!
# Turning N+1 queries into 1
for post in Post.find(:all, :include => [ :author, :comments ])
puts "Post:
" + post.title
puts "Written by:
" + post.author.name
puts "Last comment on: " + post.comments.first.created_on
end
Person.find(1, :conditions =>"administrator = 1", :order =>"created_on DESC")
Person.find(1, 5, 6, :conditions =>"administrator = 1", :order =>"created_on DESC")
Person.find(:first, :order =>"created_on DESC", :offset => 5)
Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
Person.find(:all, :offset => 10, :limit => 10)
@jlucasps

#devday2013
rails-0.13.0
➔ script.aculo.us
➔ ajax
# remote link:
link_to_remote(
"test",
:url => { :action =>"faulty" },
:update => { :success =>"good", :failure =>"bad" },
403 =>"alert('Forbidden- got ya!')",
404 =>"alert('Nothing there...?')",
:failure =>"alert('Unkown error ' + request.status)"
)

@jlucasps

#devday2013
rails-0.13.0
➔ Migrations for PostgreSQL and MySQL
➔ Rendering: One method to bind them all
➔ Named routes
map.home '', :controller => 'main', :action => 'start'
redirect_to :controller => 'main', :action => 'start'
# above route is now redirect_to :home_url

➔ Coditional validations
validates_numericality_of :income, :if => :employed?
validates_presence_of :username, :if => Proc.new { |user| user.signup_step
>1}
@jlucasps

#devday2013
rails-1.1.0
➔ RJS: JavaScript written in Ruby
➔ Polymorphic associations
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
end

class Person < ActiveRecord::Base
has_one :address, :as => :addressable
end

class Company < ActiveRecord::Base
has_one :address, :as => :addressable
end

@jlucasps

#devday2013
rails-1.1.0
➔ calculations:
◆ sum, average, count, max

➔ Eager loading
# Single database query:
companies = Company.find(:all, :include => { :groups => { :members=> { :
favorites } } })

# Just 1 database query for all of this:
authors = Author.find(:all, :include => [ { :posts => :comments }, :
categorizations ])
authors[0].posts[0].comments[0].body # => "Rock on Rails!"
authors[0].categorizations[0].name

@jlucasps

# => "Less software"

#devday2013
rails-1.2
➔ respond_to e format
class WeblogController < ActionController::Base
def index
@posts = Post.find :all
respond_to do |format|
format.html
format.xml { render :xml => @posts.to_xml }
format.rss { render :action => “feed.rxml” }
end
end
end
GET /weblog # returns HTML from browser Accept header
GET /weblog.xml # returns the XML
GET /weblog.rss # returns the RSS

@jlucasps

#devday2013
rails-2
➔ action_pack:
◆ resources e collection resources
◆ multiview (show.html.erb, show.js.erb)
◆ CRSF token
◆ record identification:
# person is a Person object, which by convention will
# be mapped to person_url for lookup
redirect_to(person)
link_to(person.name, person)
form_for(person)

@jlucasps

#devday2013
rails-2.3
➔ nested_attributes
class Book < ActiveRecord::Base
has_one :author
has_many :pages
accepts_nested_attributes_for :author, :pages
end

➔ find with having
developers = Developer.find(:all, :group => "salary", :having => "sum(salary)
> 10000", :select => "salary")

@jlucasps

#devday2013
rails-3
➔ Bundler and Gemfile
➔ New ActiveRecord query engine:
users = User.where(:name => "david").limit(20)
users.order(:name).each { |user| puts user.name }

➔ Agnosticism with jQuery, rSpec, and Data
Mapper:
◆ DataMapper -> Active Record
◆ Query -> Prototype
◆ Spec -> test/unit
@jlucasps

#devday2013
rails-3.1
➔ AssetPipeline:
◆ Sprockets, SCSS, CoffeeScript

➔ JQuery by default
➔ Reversible migrations

@jlucasps

#devday2013
rails-3.2
➔ critical security fixies:
◆ CVE-2012-5664
◆ CVE-2013-0155
◆ CVE-2013-0156
◆ CVE-2013-0333

➔ Vendor plugins -> gems
➔ Faster dev mode e routing

@jlucasps

#devday2013
rails-4
➔ Turbolinks
➔ Live streaming
➔ ActiveModel::Model
◆ validations, accessors, no persistence

➔ Deprecate routes by match
➔ Concerns routes
concern :commentable do
resources :comments
end
resources :articles, concerns: :commentable
resources :photos, concerns: :commentable
@jlucasps

#devday2013
rails-4
➔ Mass assignment protection from Models to
Controllers
class MessagesController < ApplicationController
def create
@message = Message.new(message_params)
@message.user = current_user
@message.save
end
private
def message_params
params.require(:message).permit(:content)
end
end

@jlucasps

#devday2013
Muito obrigado!
Um roadmap do Framework Ruby on
Rails
do Rails 1 ao Rails 4
João Lucas Pereira de Santana
@jlucasps

More Related Content

What's hot (7)

Java applets
Java applets
Khan Mac-arther
 
C introduction by thooyavan
C introduction by thooyavan
Thooyavan Venkatachalam
 
List,tuple,dictionary
List,tuple,dictionary
nitamhaske
 
12-greedy.ppt
12-greedy.ppt
ASVKVinayak
 
Infix prefix postfix
Infix prefix postfix
Self-Employed
 
android menus
android menus
Deepa Rani
 
C fundamental
C fundamental
Selvam Edwin
 

Similar to Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013 (20)

Intro to Ruby on Rails
Intro to Ruby on Rails
Mark Menard
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
Doris Chen
 
Ruby/Rails
Ruby/Rails
rstankov
 
Rapid Prototyping with Solr
Rapid Prototyping with Solr
Erik Hatcher
 
Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019
Adam Tomat
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
Mike Subelsky
 
What's new in Rails 4
What's new in Rails 4
Fabio Akita
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
Alive Kuo
 
Rapid Prototyping with Solr
Rapid Prototyping with Solr
Erik Hatcher
 
Javascript first-class citizenery
Javascript first-class citizenery
toddbr
 
FamilySearch Reference Client
FamilySearch Reference Client
Dallan Quass
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
Rabble .
 
20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final
David Lapsley
 
Intro to-rails-webperf
Intro to-rails-webperf
New Relic
 
An Introduction to Tornado
An Introduction to Tornado
Gavin Roy
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
crokitta
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
Jens-Christian Fischer
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Rabble .
 
Choosing a Javascript Framework
Choosing a Javascript Framework
All Things Open
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
Oscar Merida
 
Intro to Ruby on Rails
Intro to Ruby on Rails
Mark Menard
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
Doris Chen
 
Ruby/Rails
Ruby/Rails
rstankov
 
Rapid Prototyping with Solr
Rapid Prototyping with Solr
Erik Hatcher
 
Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019
Adam Tomat
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
Mike Subelsky
 
What's new in Rails 4
What's new in Rails 4
Fabio Akita
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
Alive Kuo
 
Rapid Prototyping with Solr
Rapid Prototyping with Solr
Erik Hatcher
 
Javascript first-class citizenery
Javascript first-class citizenery
toddbr
 
FamilySearch Reference Client
FamilySearch Reference Client
Dallan Quass
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
Rabble .
 
20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final
David Lapsley
 
Intro to-rails-webperf
Intro to-rails-webperf
New Relic
 
An Introduction to Tornado
An Introduction to Tornado
Gavin Roy
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
crokitta
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Rabble .
 
Choosing a Javascript Framework
Choosing a Javascript Framework
All Things Open
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
Oscar Merida
 
Ad

More from Joao Lucas Santana (8)

Critical Rendering Path - Velocidade também é uma funcionalidade
Critical Rendering Path - Velocidade também é uma funcionalidade
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (extras)
Desenvolvimento web com Ruby on Rails (extras)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 6)
Desenvolvimento web com Ruby on Rails (parte 6)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 5)
Desenvolvimento web com Ruby on Rails (parte 5)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 4)
Desenvolvimento web com Ruby on Rails (parte 4)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 1)
Desenvolvimento web com Ruby on Rails (parte 1)
Joao Lucas Santana
 
Critical Rendering Path - Velocidade também é uma funcionalidade
Critical Rendering Path - Velocidade também é uma funcionalidade
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (extras)
Desenvolvimento web com Ruby on Rails (extras)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 6)
Desenvolvimento web com Ruby on Rails (parte 6)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 5)
Desenvolvimento web com Ruby on Rails (parte 5)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 4)
Desenvolvimento web com Ruby on Rails (parte 4)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
Joao Lucas Santana
 
Desenvolvimento web com Ruby on Rails (parte 1)
Desenvolvimento web com Ruby on Rails (parte 1)
Joao Lucas Santana
 
Ad

Recently uploaded (20)

How to Create an Event in Odoo 18 - Odoo 18 Slides
How to Create an Event in Odoo 18 - Odoo 18 Slides
Celine George
 
Allomorps and word formation.pptx - Google Slides.pdf
Allomorps and word formation.pptx - Google Slides.pdf
Abha Pandey
 
Overview of Employee in Odoo 18 - Odoo Slides
Overview of Employee in Odoo 18 - Odoo Slides
Celine George
 
What are the benefits that dance brings?
What are the benefits that dance brings?
memi27
 
Exploring Ocean Floor Features for Middle School
Exploring Ocean Floor Features for Middle School
Marie
 
THERAPEUTIC COMMUNICATION included definition, characteristics, nurse patient...
THERAPEUTIC COMMUNICATION included definition, characteristics, nurse patient...
parmarjuli1412
 
How to Manage Upselling of Subscriptions in Odoo 18
How to Manage Upselling of Subscriptions in Odoo 18
Celine George
 
Nice Dream.pdf /
Nice Dream.pdf /
ErinUsher3
 
GEOGRAPHY-Study Material [ Class 10th] .pdf
GEOGRAPHY-Study Material [ Class 10th] .pdf
SHERAZ AHMAD LONE
 
SPENT QUIZ NQL JR FEST 5.0 BY SOURAV.pptx
SPENT QUIZ NQL JR FEST 5.0 BY SOURAV.pptx
Sourav Kr Podder
 
Capitol Doctoral Presentation -June 2025.pptx
Capitol Doctoral Presentation -June 2025.pptx
CapitolTechU
 
Unit 3 Poster Sketches with annotations.pptx
Unit 3 Poster Sketches with annotations.pptx
bobby205207
 
Sustainable Innovation with Immersive Learning
Sustainable Innovation with Immersive Learning
Leonel Morgado
 
Paper 108 | Thoreau’s Influence on Gandhi: The Evolution of Civil Disobedience
Paper 108 | Thoreau’s Influence on Gandhi: The Evolution of Civil Disobedience
Rajdeep Bavaliya
 
Black and White Illustrative Group Project Presentation.pdf (1).pdf
Black and White Illustrative Group Project Presentation.pdf (1).pdf
AnnasofiaUrsini
 
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Veera Pallapu
 
How to Configure Vendor Management in Lunch App of Odoo 18
How to Configure Vendor Management in Lunch App of Odoo 18
Celine George
 
The Man In The Back – Exceptional Delaware.pdf
The Man In The Back – Exceptional Delaware.pdf
dennisongomezk
 
MATERI PPT TOPIK 1 LANDASAN FILOSOFIS PENDIDIKAN
MATERI PPT TOPIK 1 LANDASAN FILOSOFIS PENDIDIKAN
aditya23173
 
How to Manage Multi Language for Invoice in Odoo 18
How to Manage Multi Language for Invoice in Odoo 18
Celine George
 
How to Create an Event in Odoo 18 - Odoo 18 Slides
How to Create an Event in Odoo 18 - Odoo 18 Slides
Celine George
 
Allomorps and word formation.pptx - Google Slides.pdf
Allomorps and word formation.pptx - Google Slides.pdf
Abha Pandey
 
Overview of Employee in Odoo 18 - Odoo Slides
Overview of Employee in Odoo 18 - Odoo Slides
Celine George
 
What are the benefits that dance brings?
What are the benefits that dance brings?
memi27
 
Exploring Ocean Floor Features for Middle School
Exploring Ocean Floor Features for Middle School
Marie
 
THERAPEUTIC COMMUNICATION included definition, characteristics, nurse patient...
THERAPEUTIC COMMUNICATION included definition, characteristics, nurse patient...
parmarjuli1412
 
How to Manage Upselling of Subscriptions in Odoo 18
How to Manage Upselling of Subscriptions in Odoo 18
Celine George
 
Nice Dream.pdf /
Nice Dream.pdf /
ErinUsher3
 
GEOGRAPHY-Study Material [ Class 10th] .pdf
GEOGRAPHY-Study Material [ Class 10th] .pdf
SHERAZ AHMAD LONE
 
SPENT QUIZ NQL JR FEST 5.0 BY SOURAV.pptx
SPENT QUIZ NQL JR FEST 5.0 BY SOURAV.pptx
Sourav Kr Podder
 
Capitol Doctoral Presentation -June 2025.pptx
Capitol Doctoral Presentation -June 2025.pptx
CapitolTechU
 
Unit 3 Poster Sketches with annotations.pptx
Unit 3 Poster Sketches with annotations.pptx
bobby205207
 
Sustainable Innovation with Immersive Learning
Sustainable Innovation with Immersive Learning
Leonel Morgado
 
Paper 108 | Thoreau’s Influence on Gandhi: The Evolution of Civil Disobedience
Paper 108 | Thoreau’s Influence on Gandhi: The Evolution of Civil Disobedience
Rajdeep Bavaliya
 
Black and White Illustrative Group Project Presentation.pdf (1).pdf
Black and White Illustrative Group Project Presentation.pdf (1).pdf
AnnasofiaUrsini
 
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Veera Pallapu
 
How to Configure Vendor Management in Lunch App of Odoo 18
How to Configure Vendor Management in Lunch App of Odoo 18
Celine George
 
The Man In The Back – Exceptional Delaware.pdf
The Man In The Back – Exceptional Delaware.pdf
dennisongomezk
 
MATERI PPT TOPIK 1 LANDASAN FILOSOFIS PENDIDIKAN
MATERI PPT TOPIK 1 LANDASAN FILOSOFIS PENDIDIKAN
aditya23173
 
How to Manage Multi Language for Invoice in Odoo 18
How to Manage Multi Language for Invoice in Odoo 18
Celine George
 

Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013

  • 1. Um roadmap do Framework Ruby on Rails do Rails 1 ao Rails 4 João Lucas Pereira de Santana
  • 2. Apresentação João Lucas Pereira de Santana twitter | github | fb | gtalk: @jlucasps Ciência da Computação pela UFLA Desenvolvedor Ruby, Java, JavaScript Instrutor Ruby on Rails @jlucasps #devday2013
  • 3. Agenda ➔ Rails Full Stack - Request/Responder ➔ Primeira versão ◆ Active Support, Active Record, Action Pack, Action Mailer ➔ Rails 2 ➔ Rails 3 ➔ Rails 4 @jlucasps #devday2013
  • 4. Rails Full Stack ➔ Origem ◆ David Heinemeier Hansson @jlucasps #devday2013
  • 5. Rails Full Stack ➔ Rails Core Team Jeremy Kemper Michael Koziarski Yehuda Katz José Valim Santiago Pastorino Aaron Patterson Xavier Noria Jon Leighton Rafael França Andrew White Guillermo Iguaran Carlos Antonio @jlucasps #devday2013
  • 6. Rails Full Stack ➔ Framework MVC para desenvolvimento Web Session Helpers Logs Testes Middleware Controller Connections Validations Queries Callbacks Migrations @jlucasps Responders Routes Renders Assets Associations Testes HTTP/SSL Helpers Model View Builders Testes Templates Partials #devday2013
  • 7. Rails Full Stack request Web Server App Server Rails Controller Model View response @jlucasps #devday2013
  • 8. Rails Full Stack REQUEST: GET http://myapp.com/users/2/lists ACCEPTED: passado para o App Server Web Server App Server Request passado para o Rails Rails Controller Model @jlucasps View #devday2013
  • 10. Rails Full Stack Router user_lists GET /users/:user_id/lists(.:format) lists#index Controller e Action selecionadas: GET /users/2/lists CONTROLLER: "lists" ACTION: "index" NOME DA ROTA: "user_lists" @jlucasps #devday2013
  • 11. Rails Full Stack Controller Rails Router index new create update Controller Model destroy ........ View GET /users/2/lists CONTROLLER: "lists" ACTION: "index" @jlucasps ListsController Model View #devday2013
  • 12. Rails Full Stack Model @user = User.find(params[:user_id]) @lists = List.find_all_by_user_id(params[:user_id]) ListsController index new User Model Active Record tabela 'users' create Banco de dados update @jlucasps destroy ........ List Model Active Record tabela 'lists' #devday2013
  • 13. Rails Full Stack REQUEST: GET http://myapp.com/users/2/lists ACCEPTED: passado para o App Server Web Server REQUEST passado para o Rails App Server Router CONTROLLER recupera informações dos MODELS para suprir a VIEW Rails PATH e METHOD mapeados para CONTROLLER e ACTION Controller action Model @jlucasps action action View #devday2013
  • 14. Rails Full Stack View Request Headers Accept: text/html, application/xhtml+xml ListsController index View @vars @vars update app/views/lists/index.html.erb .html .html app/views/lists/update.html.erb edit .......... @jlucasps #devday2013
  • 15. Rails Full Stack HTTP Response @jlucasps #devday2013
  • 16. Rails Full Stack REQUEST: GET http://myapp.com/users/2/lists ACCEPTED: passado para o App Server Web Server REQUEST passado para o Rails App Server Router CONTROLLER recupera informações dos MODELS para suprir a VIEW VIEW cria a resposta para o RESPONSE BODY @jlucasps Rails PATH e METHOD mapeados para CONTROLLER e ACTION Controller action Model action action View #devday2013
  • 17. Rails Full Stack RESPONSE recebida :-) RESPONSE é retornada para o browser Web Server RESPONSE volta através do middleware stack App Server Rails Router VIEW cria a resposta para o RESPONSE BODY @jlucasps Controller action Model action action View #devday2013
  • 19. rails-0.10.0 ➔ Inflectors SingularToPlural = { "search" => "searches", "category" => "categories", "wife" => "wives", "series" => "series" } CamelToUnderscore = { "Product" => "product", "SpecialGuest" => "special_guest" } CamelWithModuleToUnderscoreWithSlash = { "Admin::Product" => "admin/product", "UsersSection::CommissionDepartment" => "users_section/commission_department" } ClassNameToForeignKeyWithUnderscore = { "Person" => "person_id", "MyApplication::Billing::Account" => "account_id" } ClassNameToTableName = { "PrimarySpokesman" => "primary_spokesmen", "NodeChild" => "node_children" } @jlucasps #devday2013
  • 20. rails-0.10.0 ➔ Breakpoints [0, 9] in /media/truecrypt1/rails4chat/app/controllers/pages_controller.rb 1 class PagesController < ApplicationController 2 3 def index 4 debugger => 5 @messages = Message.limit(20) 6 end 7 8 end (rdb:1) params {"controller"=>"pages", "action"=>"index"} (rdb:1) @jlucasps #devday2013
  • 21. rails-0.10.0 ➔ active_support core_ext ◆ Time # Calculations assert_equal Time.local(2006,2,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2006) assert_equal Time.local(2005,2,22,10,10,9), Time.local(2005,2,22,10,10,10).ago(1) assert_equal Time.local(2005,2,20,10,10,10), Time.local(2005,2,22,10,10,10).ago(86400*2) assert_equal Time.local(2005,1,31), Time.local(2005,2,4,10,10,10).beginning_of_week assert_equal Time.local(2005,2,4,0,0,0), Time.local(2005,2,4,10,10,10).beginning_of_day # Conversions assert_equal "February 21, 2005 17:44", Time.local(2005, 2, 21, 17, 44, 30).to_s(:long) assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date @jlucasps #devday2013
  • 22. rails-0.10.0 ➔ active_support core_ext ◆ Numeric # byte calculations 1024.kilobytes => 1.kilobyte ** 4 => 1.megabyte 1.terabyte time calculations 1.minute => 60 1.hour + 15.minutes => 4500 2.days + 4.hours + 30.minutes => 189000 @jlucasps #devday2013
  • 23. rails-0.10.0 ➔ active_support core_ext ◆ Hash # hash # stringify_keys, symbolize_keys e indifferent_access strings = { 'a' => 1, 'b' => 2 } symbols = { :a => 1, :b => 2 } mixed @jlucasps = { :a => 1, 'b' => 2 } #devday2013
  • 24. rails-0.10.0 ➔ active_support core_ext ◆ Date # Getting dates in different convenient string representations and other objects assert_equal "21 Feb", Date.new(2005, 2, 21).to_s(:short) assert_equal "February 21, 2005", Date.new(2005, 2, 21).to_s(:long) # to_time assert_equal Time.local(2005, 2, 21), Date.new(2005, 2, 21).to_time # to_date assert_equal Date.new(2005, 2, 21), Date.new(2005, 2, 21).to_date @jlucasps #devday2013
  • 25. rails-0.10.0 ➔ active_record ◆ connections: ● db2, mysql, oracle, postgresql, sqlite, sqlite3, sqlserver ◆ mapping: table "products" class Product < ActiveRecord::Base end @jlucasps #devday2013
  • 26. rails-0.10.0 ➔ active_record ◆ associations: class Firm < ActiveRecord::Base has_many has_one :clients :account belongs_to :conglomorate has_and_belongs_to_many :investors end # natural assignments: apple.account = citibank assert_equal apple.id, citibank.firm_id @jlucasps #devday2013
  • 27. rails-0.10.0 ➔ active_record ◆ validations: # Validation rules that can differ for new or existing objects class Account < ActiveRecord::Base validates_presence_of :subdomain, :name, :email_address, : password validates_uniqueness_of :subdomain validates_acceptance_of :terms_of_service, :on => :create validates_confirmation_of :password, :email_address, :on => : create end @jlucasps #devday2013
  • 28. rails-0.10.0 ➔ active_record ◆ callbacks: # Callbacks as methods or queues on the entire lifecycle # (instantiation, saving, destroying, validating, etc). :after_find, :after_initialize, :before_validation :before_validation_on_update, :after_validation :after_validation_on_update, :before_save :before_update, :after_update, :after_save :before_destroy, :after_destroy @jlucasps #devday2013
  • 29. rails-0.10.0 ➔ active_record ◆ find and dynamic methods # finds Firm.find(1, 2) Company.find_first "name = 'Next Angle'" Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first Topic.find(1, :conditions => "approved = 1") Topic.find_by_title("The First Topic") Topic.find_by_title_and_author_name("The First Topic", "David") Topic.find_all_by_content("Have a nice day") # dynamic methods next_angle.clients.find(2) next_angle.clients.empty? next_angle.clients.size @jlucasps #devday2013
  • 30. rails-0.10.0 ➔ action_pack ◆ action_controller: BlogController < ActionController::Base def show @customer = find_customer end private def find_customer() Customer.find(@params["id"]) end end @jlucasps #devday2013
  • 31. rails-0.10.0 ➔ action_pack ◆ filters: class WeblogController < ActionController::Base before_filter :authenticate, :cache, :audit after_filter { |c| c.response.body = GZip::compress(c.response.body) } end @jlucasps #devday2013
  • 32. rails-0.10.0 ➔ action_pack ◆ layouts: class WeblogController < ActionController::Base layout "weblog_layout" def hello_world end end @jlucasps #devday2013
  • 33. rails-0.10.0 ➔ action_pack ◆ scaffold: require 'account' # must be an Active Record class class AccountController < ActionController::Base scaffold :account end # templates: list, show, destroy, new, create, edit, update @jlucasps #devday2013
  • 34. rails-0.10.0 ➔ action_pack ◆ advanced redirection # Advanced redirection that makes pretty urls easy: RewriteRule ^/library/books/([A-Z]+)([0-9]+)/([-_a-zA-Z0-9]+)$ /books_controller.cgi?action=$3&type=$1&code=$2 [QSA] [L] # Accessing /library/books/ISBN/0743536703/show calls BooksController#show @jlucasps #devday2013
  • 35. rails-0.10.0 ➔ action_pack ◆ action view: <!-- Embedded Ruby for templates: --> <% for post in @posts %> Title: <%= post.title %> <% end %> <!-- Helpers for forms, dates, action links, and text: --> <%= text_field "post", "title", "size" => 30 %> <%= html_date_select(Date.today) %> <%= link_to "New post", :controller => "post", :action => "new" %> <%= truncate(post.title, 25) %> @jlucasps #devday2013
  • 36. rails-0.10.0 ➔ action_pack ◆ action view: <!-- Form building for Active Record model objects: --> <%= form "post" %> <!-- This form generates a @params["post"] array that can be used directly in a save action <!-- Rendering shared partials: --> <%= render_partial "advertisement/ad", ad %> @jlucasps #devday2013
  • 37. rails-0.10.0 ➔ action_mailer def signed_up(recipient) @recipients = recipient @subject = "[Signed up] Welcome #{recipient}" @from = "[email protected]" @sent_on = Time.local(2004, 12, 12) @body["recipient"] = recipient end ApplicationMailer.deliver_signed_up("[email protected]") # sends the email @jlucasps #devday2013
  • 38. rails-0.11.0 ➔ active_support ◆ string to date and time: assert_equal Time.utc(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time assert_equal Date.new(2005, 2, 27), "2005-02-27".to_date ➔ action_pack ◆ ajax ➔ action_mailer ◆ incoming mails @jlucasps #devday2013
  • 39. rails-0.12.0 ➔ Eager associations ➔ new Base.find API ➔ more Ajax! # Turning N+1 queries into 1 for post in Post.find(:all, :include => [ :author, :comments ]) puts "Post: " + post.title puts "Written by: " + post.author.name puts "Last comment on: " + post.comments.first.created_on end Person.find(1, :conditions =>"administrator = 1", :order =>"created_on DESC") Person.find(1, 5, 6, :conditions =>"administrator = 1", :order =>"created_on DESC") Person.find(:first, :order =>"created_on DESC", :offset => 5) Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50) Person.find(:all, :offset => 10, :limit => 10) @jlucasps #devday2013
  • 40. rails-0.13.0 ➔ script.aculo.us ➔ ajax # remote link: link_to_remote( "test", :url => { :action =>"faulty" }, :update => { :success =>"good", :failure =>"bad" }, 403 =>"alert('Forbidden- got ya!')", 404 =>"alert('Nothing there...?')", :failure =>"alert('Unkown error ' + request.status)" ) @jlucasps #devday2013
  • 41. rails-0.13.0 ➔ Migrations for PostgreSQL and MySQL ➔ Rendering: One method to bind them all ➔ Named routes map.home '', :controller => 'main', :action => 'start' redirect_to :controller => 'main', :action => 'start' # above route is now redirect_to :home_url ➔ Coditional validations validates_numericality_of :income, :if => :employed? validates_presence_of :username, :if => Proc.new { |user| user.signup_step >1} @jlucasps #devday2013
  • 42. rails-1.1.0 ➔ RJS: JavaScript written in Ruby ➔ Polymorphic associations class Address < ActiveRecord::Base belongs_to :addressable, :polymorphic => true end class Person < ActiveRecord::Base has_one :address, :as => :addressable end class Company < ActiveRecord::Base has_one :address, :as => :addressable end @jlucasps #devday2013
  • 43. rails-1.1.0 ➔ calculations: ◆ sum, average, count, max ➔ Eager loading # Single database query: companies = Company.find(:all, :include => { :groups => { :members=> { : favorites } } }) # Just 1 database query for all of this: authors = Author.find(:all, :include => [ { :posts => :comments }, : categorizations ]) authors[0].posts[0].comments[0].body # => "Rock on Rails!" authors[0].categorizations[0].name @jlucasps # => "Less software" #devday2013
  • 44. rails-1.2 ➔ respond_to e format class WeblogController < ActionController::Base def index @posts = Post.find :all respond_to do |format| format.html format.xml { render :xml => @posts.to_xml } format.rss { render :action => “feed.rxml” } end end end GET /weblog # returns HTML from browser Accept header GET /weblog.xml # returns the XML GET /weblog.rss # returns the RSS @jlucasps #devday2013
  • 45. rails-2 ➔ action_pack: ◆ resources e collection resources ◆ multiview (show.html.erb, show.js.erb) ◆ CRSF token ◆ record identification: # person is a Person object, which by convention will # be mapped to person_url for lookup redirect_to(person) link_to(person.name, person) form_for(person) @jlucasps #devday2013
  • 46. rails-2.3 ➔ nested_attributes class Book < ActiveRecord::Base has_one :author has_many :pages accepts_nested_attributes_for :author, :pages end ➔ find with having developers = Developer.find(:all, :group => "salary", :having => "sum(salary) > 10000", :select => "salary") @jlucasps #devday2013
  • 47. rails-3 ➔ Bundler and Gemfile ➔ New ActiveRecord query engine: users = User.where(:name => "david").limit(20) users.order(:name).each { |user| puts user.name } ➔ Agnosticism with jQuery, rSpec, and Data Mapper: ◆ DataMapper -> Active Record ◆ Query -> Prototype ◆ Spec -> test/unit @jlucasps #devday2013
  • 48. rails-3.1 ➔ AssetPipeline: ◆ Sprockets, SCSS, CoffeeScript ➔ JQuery by default ➔ Reversible migrations @jlucasps #devday2013
  • 49. rails-3.2 ➔ critical security fixies: ◆ CVE-2012-5664 ◆ CVE-2013-0155 ◆ CVE-2013-0156 ◆ CVE-2013-0333 ➔ Vendor plugins -> gems ➔ Faster dev mode e routing @jlucasps #devday2013
  • 50. rails-4 ➔ Turbolinks ➔ Live streaming ➔ ActiveModel::Model ◆ validations, accessors, no persistence ➔ Deprecate routes by match ➔ Concerns routes concern :commentable do resources :comments end resources :articles, concerns: :commentable resources :photos, concerns: :commentable @jlucasps #devday2013
  • 51. rails-4 ➔ Mass assignment protection from Models to Controllers class MessagesController < ApplicationController def create @message = Message.new(message_params) @message.user = current_user @message.save end private def message_params params.require(:message).permit(:content) end end @jlucasps #devday2013
  • 52. Muito obrigado! Um roadmap do Framework Ruby on Rails do Rails 1 ao Rails 4 João Lucas Pereira de Santana @jlucasps