SlideShare ist ein Scribd-Unternehmen logo
1 von 63
Downloaden Sie, um offline zu lesen
Rails for Dummies
                             Reinaldo Junior




sábado, 1 de outubro de 11
Reinaldo Junior

                     •       UFES (since 2004)
                     •       Desenvolvimento Web
                     •       phpBB
                     •       Eventos, comunidade, panelinha




sábado, 1 de outubro de 11
Plano de Vôo

                     •       Framework
                     •       Filosofia
                     •       Ruby
                     •       Rails




sábado, 1 de outubro de 11
Rails é um Framework


                     •       “Abstração” (a resposta padrão de qualquer
                             pergunta na computação)
                     •       REUSO




sábado, 1 de outubro de 11
Frameworks

                     •       Frameworks = (components + patterns)
                             Ralph E. Johnson, 1997 (GoF)
                     •       Contexto
                     •       Específico de um Domínio




sábado, 1 de outubro de 11
WIN


                     •       Vocabulário compartilhado
                     •       Restrições inteligentes
                     •       Foco na aplicação (e não no COMO)




sábado, 1 de outubro de 11
RUBY on Rails

                     •       Ruby é a linguagem           puts "maiusculo".upcase

                     •       Foco no programador          puts -5.abs


                     •       Sintaxe elegante e natural   5.times do
                                                            puts "Ruby é Massa!"
                     •       Extensibilidade              end




sábado, 1 de outubro de 11
O.o
                   class Pato
                     def quack
                       "Quack!"
                     end                 •   Tudo é um objeto
                   end
                                         •   Classes (begin ... end)
                   # Donald Duck
                   donald = Pato.new     •   Métodos (def ... end)
                   donald.quack
                   #retorna "Quack!"




sábado, 1 de outubro de 11
_Oooo_

                   class Pato                              puts Pato.new(2)
                     @@asas = 2                            # Retorna "Asas: 2/2"

                       def initialize(asas=nil)            puts Pato.new
                         @asas = [asas.to_i, @@asas].min   # Retorna "Asas: 0/2"
                       end
                                                           puts Pato.new(10)
                     def to_s                              # Retorna "Asas: 2/2"
                       "Asas: #{@asas}/#{@@asas}"
                     end                                   puts Pato.new.quack
                   end                                     # Retorna "Quack!"




sábado, 1 de outubro de 11
Mixin
                                                         class Pato
                   module Mortal                           include Mortal
                     def machucado?                      end
                       @asas < @@asas
                     end                                 class Ganso < Pato
                                                           # Err...
                       def morto?                        end
                         @asas.to_i.zero?
                       end                               class Ganso
                                                           include Mortal
                     def machuca
                       @asas = @asas - 1 unless morto?     def quack
                     end                                     "Ãhhn, Âhhn!"
                   end                                     end
                                                         end




sábado, 1 de outubro de 11
Duck-typing

                   def faz_quack_quack(patos)
                     patos.each do |pato|
                       if pato.respond_to? :quack
                         puts pato.quack
                       end
                     end
                   end

                   coisas = [Pato.new, Ganso.new, Pessoa.new]
                   faz_quack_quack(coisas)




sábado, 1 de outubro de 11
Blocos
                   people.each do |person|
                     puts "* #{person.name}"
                   end
                                                def em_par
                                                  yield
                   5.times {
                                                  yield
                     puts "Ruby rocks!"
                                                end
                   }
                                                em_par {
                   [2,1,3].sort! { |a, b|
                                                  "Tentativa #{i}"
                     b <=> a
                                                }
                   }

                   (0..10).each{ |i| puts i }




sábado, 1 de outubro de 11
Enumeráveis
                   # Array
                                                   0..10 # Range
                   [1, 5, true, "Reinaldo", nil]
                                                   :reinaldo # Simbolo
                   # Hash
                   evento = {
                                                   evento['ano']
                     'nome' => 'RockAndRails',
                                                   # 2011
                     'ano' => 2011 }
                                                   reinaldo[:nome]
                   reinaldo = {
                                                   # ‘Reinaldo’
                     :nome => 'Reinaldo',
                     :cidade => 'Vila Velha',
                                                   reinaldo[:dindin]
                     :idade => 25
                                                   # nil
                   }




sábado, 1 de outubro de 11
Ruby Way
                   def caminho(options={})
                     default = {
                       :origem => 'Vitória', :destino => 'Vila Velha'
                     }
                     opt = default.merge(options)

                     "#{opt[:origem]} --> #{opt[:destino]}"
                   end

                   caminho()
                   caminho(:origem => 'Campos')
                   caminho(:destino => 'São Paulo')
                   caminho :destino => 'Macaé', :origem => 'Manaus'




sábado, 1 de outubro de 11
Ruby on Rails

                     •       DRY - Don’t Repeat Yourself
                     •       COC - Convention Over Configuration
                     •       Preguiça Virtuosa (aka Automatização)
                     •       MVC, REST
                     •       Comunidade



sábado, 1 de outubro de 11
Instalando
                     •       Windows

                             •   http://railsinstaller.org/
                     •       Linux
                             •   apt-get install ruby irb rubygems

                             •   gem update --system
                             •   gem install rails
                     •       Mac (já vem instalado)


sábado, 1 de outubro de 11
Criando uma Aplicação
                                                ~ $ rails new dummy
                                                [...]

                     •       Estrutura de       ~ $ cd dummy
                             arquivos definida
                                                ~/dummy $


                   ~/dummy $ ls

                   Gemfile	 app	 	 	 db	 	 log	 	 	 test
                           	              	
                   README	 	 config	 	 doc	 	 public	 	 tmp
                   Rakefile	 config.ru	lib	 	 script	 	 vendor




sábado, 1 de outubro de 11
Iniciando a App

                   ~/dummy $ rails server
                   Could not find gem 'sqlite3 (>= 0) ruby' in any of the
                   gem sources listed in your Gemfile.
                   Run `bundle install` to install missing gems.

                   ~/dummy $ bundle install
                   Fetching source index for http://rubygems.org/
                   [...]
                   Your bundle is complete! Use `bundle show [gemname]`
                   to see where a bundled gem is installed.




sábado, 1 de outubro de 11
Executando o Web
                                  Server
                   ~/dummy $ rails server
                   => Booting WEBrick
                   => Rails 3.0.10 application starting in development on
                   http://0.0.0.0:3000
                   => Call with -d to detach
                   => Ctrl-C to shutdown server

                   ~/dummy $ rails server -d
                   ~/dummy $ tail -f log/development.log




sábado, 1 de outubro de 11
It Just Works™




sábado, 1 de outubro de 11
Gerando o primeiro
                                  código
                   ~/dummy $ rails generate scaffold Post title:string
                   body:text rating:decimal viewed:integer	

                   ~/dummy $ rails generate model [...]
                   ~/dummy $ rails generate migration [...]
                   ~/dummy $ rails generate controller [...]

                   ~/dummy $ rails destroy

                   ~/dummy $ rails [comando] --help




sábado, 1 de outubro de 11
“Teste de Integração”




sábado, 1 de outubro de 11
“Teste Unitário”
                   ~/dummy $ rails console
                   Loading development environment (Rails 3.0.10)
                   :001 > Post
                    => Post(Table doesn't exist)

                   :002 > Post.all
                   ActiveRecord::StatementInvalid: SQLite3::SQLException:
                   no such table: posts: SELECT "posts".* FROM "posts"
                   	 from [...]




sábado, 1 de outubro de 11
Mais preguiça

                   ~/dummy $ rake db:create
                   [...]

                   ~/dummy $ rake db:migrate
                   == CreatePosts: migrating ==========================
                   -- create_table(:posts)
                      -> 0.0019s
                   == CreatePosts: migrated (0.0020s) =================




sábado, 1 de outubro de 11
Di Grátis




sábado, 1 de outubro de 11
sábado, 1 de outubro de 11
Rails e MVC




                        Agile Web Development With Rails, 3rd Ed.


sábado, 1 de outubro de 11
Componentes




                        Agile Web Development With Rails, 3rd Ed.


sábado, 1 de outubro de 11
Arquitetura




sábado, 1 de outubro de 11
Model


                     •       Mantém o estado da aplicação (persistente ou
                             não)
                     •       Regras de negócio que se aplicam ao estado




sábado, 1 de outubro de 11
ActiveRecord = ORM
                     •       OO <=> DB relacional
                             •   tabelas <=> classes
                             •   registros <=> objetos
                             •   colunas <=> propriedades
                     •       Tudo isso SEM SQL
                     •       90% da sua aplicação


sábado, 1 de outubro de 11
Migrations
                   # db/migrate/20110930150650_create_posts.rb
                   class CreatePosts < ActiveRecord::Migration
                     def self.up
                       create_table :posts do |t|
                         t.string :title
                         t.text :body
                         t.decimal :rating
                         t.integer :viewed

                           t.timestamps    # created_at e updated_at
                         end
                       end

                     def self.down
                       drop_table :posts
                     end
                   end


sábado, 1 de outubro de 11
posts
                         title       body         viewed
                                                           •   Tabela no plural
                    Rock And
                                 Bla bla bla...     3
                      Rails
                                                           •   Classe no singular
                    Inscrições
                      abertas
                                   Etc e tal        2
                                                           •   app/models/<classe>.rb


                   # app/models/post.rb
                   class Post < ActiveRecord::Base
                     # Sim, só isso
                   end

                   novo = Post.new :title => 'O evento começou'
                   post = Post.find(3)
                   Post.destroy(2)




sábado, 1 de outubro de 11
novo = Post.new(
                     :title => 'O evento começou',
                     :body => '...'
                   )
                   novo.save

                   post = Post.find(3)
                   post[:title]
                   post.viewed

                   post.body = 'Atualizações'
                   post.save

                   Post.all
                   Post.find_by_title('Rock and Rails')
                   Post.find_all_viewed(3)

                   Post.where('viewed >= ?', 50).order('title ASC')




sábado, 1 de outubro de 11
Validação



                     •       LT do Uriel (guenta aí)




sábado, 1 de outubro de 11
Associações
                                             class Comment < ActiveRecord::Base
                                               belongs_to :user
                                               belongs_to :post
                                             end

                                             class User < ActiveRecord::Base
                                               has_many :comments # fui eu
                                             end


                   ~/dummy $ rails generate scaffold User name:string
                   email:string

                   ~/dummy $ rails generate scaffold Comment body:text
                   viewed:integer user:references post:references



sábado, 1 de outubro de 11
~/dummy $ rake db:migrate


                   comentario = Comment.first
                   comentario.post     # objeto
                   comentario.user_id # id

                   meus_comentarios = Comment.find_all_by_user_id(3)

                   eu = User.find_by_name('Reinaldo')
                   eu.comments     # [objeto, objeto, ...]
                   eu.comment_ids # [id, id, ...]
                   eu.comments.find(3)
                   eu.comments.where('viewed >=', 50)




sábado, 1 de outubro de 11
eu = User.find_by_name('Reinaldo')

                   novo = eu.comments.create(:body => 'Massa!')
                   popular = eu.comments.order('viewed DESC').limit(1)

                   outro = Comment.new(:body => 'Rox!')
                   outro.user = User.find_or_create_by_name_and_email(
                     'M3nd3s', 'm3nd3s@gmail.com'
                   )
                   outro.save




sábado, 1 de outubro de 11
Many-to-Many
                              ~/dummy $ rails generate model
                              Authorship post:references
                              user:references order:integer


                              class Post   < ActiveRecord::Base
                                has_many   :comments
                                has_many   :authorships
                                has_many   :users, :through => :authorships
                              end

                              class Authorship < ActiveRecord::Base
                                belongs_to :post
                                belongs_to :user
                              end




sábado, 1 de outubro de 11
post = Post.new(
                               :title => 'Give me Fuel!'
                             )
                             post.users << User.first
                             post.save

                             post.authorships

                             post.authorships << Authorship.create(
                               :user => User.find(3),
                               :order => 1
                             )




sábado, 1 de outubro de 11
class Post < ActiveRecord::Base
                                                     post = Post.first
                     has_many :comments
                                                     reinaldo = User.first
                     has_many :authorships

                       has_many :authors,            post.authors << reinaldo
                         :through => :authorships,   post.authorships
                         :source => :user
                                                     comment = Comment.new(
                     has_many :commenters,             :body => 'Yeah',
                       :through => :comments,          :user => User.find(2)
                       :source => :user
                                                     )
                   end
                                                     post.comments << comment

                                                     post.save
                   class User < ActiveRecord::Base
                     has_many :comments              post.reload
                     has_many :authorships           reinaldo.reload
                     has_many :posts,
                       :through => :authorships      post.commenters
                   end                               reinaldo.posts




sábado, 1 de outubro de 11
Rotas

                     •       Avaliam as requisições e encaminham para
                             um Controller + Action
                     •       Criam métodos (helpers) que geram URLs
                     •       Requisição HTTP: caminho (URI) e método
                             HTTP (GET, POST, PUT, DELETE)




sábado, 1 de outubro de 11
Fluxo

                     •       http://localhost:3000/say/hello
                     •       Cliente => Servidor => Web Server
                             •   Rota => Controller => Action => View
                     •       Servidor => Cliente




sábado, 1 de outubro de 11
Configurando as rotas
                   # config/routes.rb
                   Dummy::Application.routes.draw do

                        # Suas rotas aqui
                        get '/say/hello/',
                          :controller => 'say',
                          :action => 'hello'

                        get '/say/goodbye' => 'say#goodbye'

                     post '/say/hey-ya' => 'say#hello'
                   end




sábado, 1 de outubro de 11
~/dummy $ rake routes

                     say_hello     GET    /say/hello(.:format)
                                 {:controller=>"say", :action=>"hello"}

                     say_goodbye GET    /say/goodbye(.:format)
                               {:controller=>"say", :action=>"goodbye"}

                                   POST   /say/hey-ya(.:format)
                                 {:controller=>"say", :action=>"hello"}




sábado, 1 de outubro de 11
Métodos

                   say_hello_path()
                   say_hello_url()

                   say_goodbye_path
                   say_goodbye_url

                   link_to("Diz olá pra mim!", say_hello_path())
                   link_to "Tchau!", say_goodbye_url




sábado, 1 de outubro de 11
REST
                     •       REST (Representational State Trasfer)
                     •       Roy Fielding (Tese de Ph.D. ), cara do HTTP
                     •       Princípios
                             •   Protocolo sem estado
                             •   Recursos, identificados universalmente (URI)
                             •   Operações bem definidas que se aplicam a todos
                                 os recursos
                             •   Múltiplas representações do mesmo recurso


sábado, 1 de outubro de 11
Recursos
                                          Método            Path    Action
                                           GET     /posts           index
                                           GET     /posts/new        new
                   resources :posts
                                           POST    /posts           create
                   resources :comments
                                           GET     /posts/:id        show
                   resources :users
                                           GET     /posts/:id/new    edit
                                           PUT     /posts/:id       update
                                          DELETE   /posts/:id       destroy


                   link_to("Listar posts", posts_path())
                   link_to "Veja os posts", posts_path
                   link_to "Leia esse post", show_post_url(@post)
                   link_to "Leia esse post", @post




sábado, 1 de outubro de 11
Controllers

                     •       Subclasse de ActionController::Base
                     •       Convenção
                             •   app/controllers/<nome>_controller.rb
                             •   class <Nome>Controller
                             •   Se for um controller de recursos, nome é
                                 no plural



sábado, 1 de outubro de 11
Actions
                     •       Métodos do públicos do Controller
                     •       Renderiza Views para gerar a resposta
                     •       Disponibiliza variáveis de instância pra View
                     •       Acesso aos parâmetros pelo hash “params”
                     •       Convenção
                             •   renderiza uma view com o mesmo nome


sábado, 1 de outubro de 11
# app/controllers/say_controller.rb
                   class SayController < ApplicationController
                     before_filter :get_time

                        def hello
                          @message = params[:message] || 'Olá amigo!'
                        end

                        def goodbye
                          @message = params[:message] || 'Até mais, colega!'
                        end

                     protected
                     def get_time
                       @time = Time.now
                     end
                   end




sábado, 1 de outubro de 11
Feels like ASP/PHP
                   <!-- app/views/say/hello.html.erb -->
                   <p>
                     <strong><%= @message %></strong><br />
                     Você chegou às <em><%= @time %></em>.
                   </p>



                   <!-- app/views/say/goodbye.html.erb -->
                   <p>
                     <strong><%= @message %></strong><br />
                     Você está saindo às <em><%= @time %></em>.
                   </p>




sábado, 1 de outubro de 11
redirect_to, render
                   # app/controllers/posts_controller.rb
                   class PostsController < ApplicationController

                       # POST /posts
                       def create
                         @post = Post.new(params[:post])

                         if @post.save
                           redirect_to(@post, :notice => 'Post criado com sucesso.')
                         else
                           render :action => "new"
                         end
                       end

                   end




sábado, 1 de outubro de 11
Views
                     •       Handlers

                             •   ERB, RJS, Builder, RHTML, RXML
                     •       Formats
                             •   html, xml, json, js

                     •       Convenção
                             •   app/views/<controller>/
                             •   <view>.<formato>.<handler>


sábado, 1 de outubro de 11
Rendering
                   # app/controllers/posts_controller.rb
                   class PostsController < ApplicationController

                       def index
                         @posts = Post.all
                       end

                   end




sábado, 1 de outubro de 11
<!-- app/views/posts/index.html.erb -->
                   <h1>Nossos Posts</h1>

                   <% @posts.each do |post| %>
                     <h2><%= post.title %></h2>
                     <div class="rating"><%= post.rating %></div>
                     <%= link_to 'Leia na íntegra', post %>
                   <% end %>




sábado, 1 de outubro de 11
Partials
                   <!-- app/views/posts/index.html.erb -->
                   <h1>Post em nosso site</h1>
                   <%= render @posts %>




                   <!-- app/views/posts/_post.html.erb -->
                   <h2><%= post.title %></h2>
                   <div class="rating"><%= post.rating %></div>
                   <%= link_to 'Leia na íntegra', post %>




sábado, 1 de outubro de 11
Helpers
                   <%= image_tag('rails.png') %>
                   <img alt="Rails" src="/images/rails.png" />

                   <%= stylesheet_link_tag('application') %>
                   <link href="/stylesheets/application.css"
                   media="screen" rel="stylesheet" type="text/css" />

                   <%= javascript_include_tag('mapa') %>
                   <script type="text/javascript" src="/javascripts/
                   mapa.js"></script>

                   <% time_ago_in_words(post.created_at)%>
                   <!-- 3 minutos atrás -->




sábado, 1 de outubro de 11
Form Helpers
                   <%= form_for(@post) do |f| %>
                     <div class="field">
                       <%= f.label :title %><br />
                       <%= f.text_field :title %>
                     </div>
                     <div class="field">
                       <%= f.label :body %><br />
                       <%= f.text_area :body %>
                     </div>
                     <div class="actions">
                       <%= f.submit %>
                     </div>
                   <% end %>




sábado, 1 de outubro de 11
ActiveSupport
                   1.ordinalize # 1st
                   100.ordinalize # 100th
                   1.gigabyte / 512.kilobytes
                   # 2048
                                                1.month.from_now
                   "author_id".humanize         3.days.ago
                   # Author id                  10.minutes.from_now

                   "post".pluralize             Time.now + 2.hours
                   # posts
                                                date.at_beginning_of_week
                   "primeiro evento".titleize
                   # Primeiro Evento




sábado, 1 de outubro de 11
Perguntas?
                     •       Rails Escala?
                             Saying “Rails doesn’t scale” is like saying “my car doesn’t go
                             infinitely fast”
                             - Pushion Passenger Team
                     •       Posso usar XYZ com Rails? SIM
                     •       Rails é melhor que XYZ? SIM e NÃO
                     •       Rails é bom apenas pra CRUD? NÃO e SIM
                     •       Qual o salário de programador Rails? ...
                     •       Como faço XYZ com Rails? Google!


sábado, 1 de outubro de 11
http://reinaldojunior.net :: @ReinaldoJunior



sábado, 1 de outubro de 11
Créditos das Imagens

                     •       http://vvn.net/wp/2008/09/18/ruby-on-rails-
                             architecture/
                     •       Agile Web Development With Rails, 3rd Ed.
                     •       yUML.me




sábado, 1 de outubro de 11

Weitere ähnliche Inhalte

Andere mochten auch

website usability evaluation of two top airlines in the Philippines offering ...
website usability evaluation of two top airlines in the Philippines offering ...website usability evaluation of two top airlines in the Philippines offering ...
website usability evaluation of two top airlines in the Philippines offering ...
Angelica Angelo Ocon
 
JavaScript ninja com jQuery
JavaScript ninja com jQueryJavaScript ninja com jQuery
JavaScript ninja com jQuery
Reinaldo Junior
 
Aprender Javascript e jQuery (UFCD
Aprender Javascript e jQuery (UFCDAprender Javascript e jQuery (UFCD
Aprender Javascript e jQuery (UFCD
Afonso Gomes
 

Andere mochten auch (6)

Jquery Mobile
Jquery MobileJquery Mobile
Jquery Mobile
 
Comparing native Android and jQuery Mobile capabilities (Presentation)
Comparing native Android and jQuery Mobile capabilities (Presentation)Comparing native Android and jQuery Mobile capabilities (Presentation)
Comparing native Android and jQuery Mobile capabilities (Presentation)
 
website usability evaluation of two top airlines in the Philippines offering ...
website usability evaluation of two top airlines in the Philippines offering ...website usability evaluation of two top airlines in the Philippines offering ...
website usability evaluation of two top airlines in the Philippines offering ...
 
JavaScript ninja com jQuery
JavaScript ninja com jQueryJavaScript ninja com jQuery
JavaScript ninja com jQuery
 
Boas Práticas em jQuery
Boas Práticas em jQueryBoas Práticas em jQuery
Boas Práticas em jQuery
 
Aprender Javascript e jQuery (UFCD
Aprender Javascript e jQuery (UFCDAprender Javascript e jQuery (UFCD
Aprender Javascript e jQuery (UFCD
 

Kürzlich hochgeladen

Assessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdfAssessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdf
Natalia Granato
 

Kürzlich hochgeladen (6)

ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object Calisthenics
 
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemplo
 
Assessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdfAssessement Boas Praticas em Kubernetes.pdf
Assessement Boas Praticas em Kubernetes.pdf
 

Rails for Dummies

  • 1. Rails for Dummies Reinaldo Junior sábado, 1 de outubro de 11
  • 2. Reinaldo Junior • UFES (since 2004) • Desenvolvimento Web • phpBB • Eventos, comunidade, panelinha sábado, 1 de outubro de 11
  • 3. Plano de Vôo • Framework • Filosofia • Ruby • Rails sábado, 1 de outubro de 11
  • 4. Rails é um Framework • “Abstração” (a resposta padrão de qualquer pergunta na computação) • REUSO sábado, 1 de outubro de 11
  • 5. Frameworks • Frameworks = (components + patterns) Ralph E. Johnson, 1997 (GoF) • Contexto • Específico de um Domínio sábado, 1 de outubro de 11
  • 6. WIN • Vocabulário compartilhado • Restrições inteligentes • Foco na aplicação (e não no COMO) sábado, 1 de outubro de 11
  • 7. RUBY on Rails • Ruby é a linguagem puts "maiusculo".upcase • Foco no programador puts -5.abs • Sintaxe elegante e natural 5.times do puts "Ruby é Massa!" • Extensibilidade end sábado, 1 de outubro de 11
  • 8. O.o class Pato def quack "Quack!" end • Tudo é um objeto end • Classes (begin ... end) # Donald Duck donald = Pato.new • Métodos (def ... end) donald.quack #retorna "Quack!" sábado, 1 de outubro de 11
  • 9. _Oooo_ class Pato puts Pato.new(2) @@asas = 2 # Retorna "Asas: 2/2" def initialize(asas=nil) puts Pato.new @asas = [asas.to_i, @@asas].min # Retorna "Asas: 0/2" end puts Pato.new(10) def to_s # Retorna "Asas: 2/2" "Asas: #{@asas}/#{@@asas}" end puts Pato.new.quack end # Retorna "Quack!" sábado, 1 de outubro de 11
  • 10. Mixin class Pato module Mortal include Mortal def machucado? end @asas < @@asas end class Ganso < Pato # Err... def morto? end @asas.to_i.zero? end class Ganso include Mortal def machuca @asas = @asas - 1 unless morto? def quack end "Ãhhn, Âhhn!" end end end sábado, 1 de outubro de 11
  • 11. Duck-typing def faz_quack_quack(patos) patos.each do |pato| if pato.respond_to? :quack puts pato.quack end end end coisas = [Pato.new, Ganso.new, Pessoa.new] faz_quack_quack(coisas) sábado, 1 de outubro de 11
  • 12. Blocos people.each do |person| puts "* #{person.name}" end def em_par yield 5.times { yield puts "Ruby rocks!" end } em_par { [2,1,3].sort! { |a, b| "Tentativa #{i}" b <=> a } } (0..10).each{ |i| puts i } sábado, 1 de outubro de 11
  • 13. Enumeráveis # Array 0..10 # Range [1, 5, true, "Reinaldo", nil] :reinaldo # Simbolo # Hash evento = { evento['ano'] 'nome' => 'RockAndRails', # 2011 'ano' => 2011 } reinaldo[:nome] reinaldo = { # ‘Reinaldo’ :nome => 'Reinaldo', :cidade => 'Vila Velha', reinaldo[:dindin] :idade => 25 # nil } sábado, 1 de outubro de 11
  • 14. Ruby Way def caminho(options={}) default = { :origem => 'Vitória', :destino => 'Vila Velha' } opt = default.merge(options) "#{opt[:origem]} --> #{opt[:destino]}" end caminho() caminho(:origem => 'Campos') caminho(:destino => 'São Paulo') caminho :destino => 'Macaé', :origem => 'Manaus' sábado, 1 de outubro de 11
  • 15. Ruby on Rails • DRY - Don’t Repeat Yourself • COC - Convention Over Configuration • Preguiça Virtuosa (aka Automatização) • MVC, REST • Comunidade sábado, 1 de outubro de 11
  • 16. Instalando • Windows • http://railsinstaller.org/ • Linux • apt-get install ruby irb rubygems • gem update --system • gem install rails • Mac (já vem instalado) sábado, 1 de outubro de 11
  • 17. Criando uma Aplicação ~ $ rails new dummy [...] • Estrutura de ~ $ cd dummy arquivos definida ~/dummy $ ~/dummy $ ls Gemfile app db log test README config doc public tmp Rakefile config.ru lib script vendor sábado, 1 de outubro de 11
  • 18. Iniciando a App ~/dummy $ rails server Could not find gem 'sqlite3 (>= 0) ruby' in any of the gem sources listed in your Gemfile. Run `bundle install` to install missing gems. ~/dummy $ bundle install Fetching source index for http://rubygems.org/ [...] Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. sábado, 1 de outubro de 11
  • 19. Executando o Web Server ~/dummy $ rails server => Booting WEBrick => Rails 3.0.10 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server ~/dummy $ rails server -d ~/dummy $ tail -f log/development.log sábado, 1 de outubro de 11
  • 20. It Just Works™ sábado, 1 de outubro de 11
  • 21. Gerando o primeiro código ~/dummy $ rails generate scaffold Post title:string body:text rating:decimal viewed:integer ~/dummy $ rails generate model [...] ~/dummy $ rails generate migration [...] ~/dummy $ rails generate controller [...] ~/dummy $ rails destroy ~/dummy $ rails [comando] --help sábado, 1 de outubro de 11
  • 23. “Teste Unitário” ~/dummy $ rails console Loading development environment (Rails 3.0.10) :001 > Post => Post(Table doesn't exist) :002 > Post.all ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: posts: SELECT "posts".* FROM "posts" from [...] sábado, 1 de outubro de 11
  • 24. Mais preguiça ~/dummy $ rake db:create [...] ~/dummy $ rake db:migrate == CreatePosts: migrating ========================== -- create_table(:posts) -> 0.0019s == CreatePosts: migrated (0.0020s) ================= sábado, 1 de outubro de 11
  • 25. Di Grátis sábado, 1 de outubro de 11
  • 26. sábado, 1 de outubro de 11
  • 27. Rails e MVC Agile Web Development With Rails, 3rd Ed. sábado, 1 de outubro de 11
  • 28. Componentes Agile Web Development With Rails, 3rd Ed. sábado, 1 de outubro de 11
  • 29. Arquitetura sábado, 1 de outubro de 11
  • 30. Model • Mantém o estado da aplicação (persistente ou não) • Regras de negócio que se aplicam ao estado sábado, 1 de outubro de 11
  • 31. ActiveRecord = ORM • OO <=> DB relacional • tabelas <=> classes • registros <=> objetos • colunas <=> propriedades • Tudo isso SEM SQL • 90% da sua aplicação sábado, 1 de outubro de 11
  • 32. Migrations # db/migrate/20110930150650_create_posts.rb class CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.string :title t.text :body t.decimal :rating t.integer :viewed t.timestamps # created_at e updated_at end end def self.down drop_table :posts end end sábado, 1 de outubro de 11
  • 33. posts title body viewed • Tabela no plural Rock And Bla bla bla... 3 Rails • Classe no singular Inscrições abertas Etc e tal 2 • app/models/<classe>.rb # app/models/post.rb class Post < ActiveRecord::Base # Sim, só isso end novo = Post.new :title => 'O evento começou' post = Post.find(3) Post.destroy(2) sábado, 1 de outubro de 11
  • 34. novo = Post.new( :title => 'O evento começou', :body => '...' ) novo.save post = Post.find(3) post[:title] post.viewed post.body = 'Atualizações' post.save Post.all Post.find_by_title('Rock and Rails') Post.find_all_viewed(3) Post.where('viewed >= ?', 50).order('title ASC') sábado, 1 de outubro de 11
  • 35. Validação • LT do Uriel (guenta aí) sábado, 1 de outubro de 11
  • 36. Associações class Comment < ActiveRecord::Base belongs_to :user belongs_to :post end class User < ActiveRecord::Base has_many :comments # fui eu end ~/dummy $ rails generate scaffold User name:string email:string ~/dummy $ rails generate scaffold Comment body:text viewed:integer user:references post:references sábado, 1 de outubro de 11
  • 37. ~/dummy $ rake db:migrate comentario = Comment.first comentario.post # objeto comentario.user_id # id meus_comentarios = Comment.find_all_by_user_id(3) eu = User.find_by_name('Reinaldo') eu.comments # [objeto, objeto, ...] eu.comment_ids # [id, id, ...] eu.comments.find(3) eu.comments.where('viewed >=', 50) sábado, 1 de outubro de 11
  • 38. eu = User.find_by_name('Reinaldo') novo = eu.comments.create(:body => 'Massa!') popular = eu.comments.order('viewed DESC').limit(1) outro = Comment.new(:body => 'Rox!') outro.user = User.find_or_create_by_name_and_email( 'M3nd3s', 'm3nd3s@gmail.com' ) outro.save sábado, 1 de outubro de 11
  • 39. Many-to-Many ~/dummy $ rails generate model Authorship post:references user:references order:integer class Post < ActiveRecord::Base has_many :comments has_many :authorships has_many :users, :through => :authorships end class Authorship < ActiveRecord::Base belongs_to :post belongs_to :user end sábado, 1 de outubro de 11
  • 40. post = Post.new( :title => 'Give me Fuel!' ) post.users << User.first post.save post.authorships post.authorships << Authorship.create( :user => User.find(3), :order => 1 ) sábado, 1 de outubro de 11
  • 41. class Post < ActiveRecord::Base post = Post.first has_many :comments reinaldo = User.first has_many :authorships has_many :authors, post.authors << reinaldo :through => :authorships, post.authorships :source => :user comment = Comment.new( has_many :commenters, :body => 'Yeah', :through => :comments, :user => User.find(2) :source => :user ) end post.comments << comment post.save class User < ActiveRecord::Base has_many :comments post.reload has_many :authorships reinaldo.reload has_many :posts, :through => :authorships post.commenters end reinaldo.posts sábado, 1 de outubro de 11
  • 42. Rotas • Avaliam as requisições e encaminham para um Controller + Action • Criam métodos (helpers) que geram URLs • Requisição HTTP: caminho (URI) e método HTTP (GET, POST, PUT, DELETE) sábado, 1 de outubro de 11
  • 43. Fluxo • http://localhost:3000/say/hello • Cliente => Servidor => Web Server • Rota => Controller => Action => View • Servidor => Cliente sábado, 1 de outubro de 11
  • 44. Configurando as rotas # config/routes.rb Dummy::Application.routes.draw do # Suas rotas aqui get '/say/hello/', :controller => 'say', :action => 'hello' get '/say/goodbye' => 'say#goodbye' post '/say/hey-ya' => 'say#hello' end sábado, 1 de outubro de 11
  • 45. ~/dummy $ rake routes say_hello GET /say/hello(.:format) {:controller=>"say", :action=>"hello"} say_goodbye GET /say/goodbye(.:format) {:controller=>"say", :action=>"goodbye"} POST /say/hey-ya(.:format) {:controller=>"say", :action=>"hello"} sábado, 1 de outubro de 11
  • 46. Métodos say_hello_path() say_hello_url() say_goodbye_path say_goodbye_url link_to("Diz olá pra mim!", say_hello_path()) link_to "Tchau!", say_goodbye_url sábado, 1 de outubro de 11
  • 47. REST • REST (Representational State Trasfer) • Roy Fielding (Tese de Ph.D. ), cara do HTTP • Princípios • Protocolo sem estado • Recursos, identificados universalmente (URI) • Operações bem definidas que se aplicam a todos os recursos • Múltiplas representações do mesmo recurso sábado, 1 de outubro de 11
  • 48. Recursos Método Path Action GET /posts index GET /posts/new new resources :posts POST /posts create resources :comments GET /posts/:id show resources :users GET /posts/:id/new edit PUT /posts/:id update DELETE /posts/:id destroy link_to("Listar posts", posts_path()) link_to "Veja os posts", posts_path link_to "Leia esse post", show_post_url(@post) link_to "Leia esse post", @post sábado, 1 de outubro de 11
  • 49. Controllers • Subclasse de ActionController::Base • Convenção • app/controllers/<nome>_controller.rb • class <Nome>Controller • Se for um controller de recursos, nome é no plural sábado, 1 de outubro de 11
  • 50. Actions • Métodos do públicos do Controller • Renderiza Views para gerar a resposta • Disponibiliza variáveis de instância pra View • Acesso aos parâmetros pelo hash “params” • Convenção • renderiza uma view com o mesmo nome sábado, 1 de outubro de 11
  • 51. # app/controllers/say_controller.rb class SayController < ApplicationController before_filter :get_time def hello @message = params[:message] || 'Olá amigo!' end def goodbye @message = params[:message] || 'Até mais, colega!' end protected def get_time @time = Time.now end end sábado, 1 de outubro de 11
  • 52. Feels like ASP/PHP <!-- app/views/say/hello.html.erb --> <p> <strong><%= @message %></strong><br /> Você chegou às <em><%= @time %></em>. </p> <!-- app/views/say/goodbye.html.erb --> <p> <strong><%= @message %></strong><br /> Você está saindo às <em><%= @time %></em>. </p> sábado, 1 de outubro de 11
  • 53. redirect_to, render # app/controllers/posts_controller.rb class PostsController < ApplicationController # POST /posts def create @post = Post.new(params[:post]) if @post.save redirect_to(@post, :notice => 'Post criado com sucesso.') else render :action => "new" end end end sábado, 1 de outubro de 11
  • 54. Views • Handlers • ERB, RJS, Builder, RHTML, RXML • Formats • html, xml, json, js • Convenção • app/views/<controller>/ • <view>.<formato>.<handler> sábado, 1 de outubro de 11
  • 55. Rendering # app/controllers/posts_controller.rb class PostsController < ApplicationController def index @posts = Post.all end end sábado, 1 de outubro de 11
  • 56. <!-- app/views/posts/index.html.erb --> <h1>Nossos Posts</h1> <% @posts.each do |post| %> <h2><%= post.title %></h2> <div class="rating"><%= post.rating %></div> <%= link_to 'Leia na íntegra', post %> <% end %> sábado, 1 de outubro de 11
  • 57. Partials <!-- app/views/posts/index.html.erb --> <h1>Post em nosso site</h1> <%= render @posts %> <!-- app/views/posts/_post.html.erb --> <h2><%= post.title %></h2> <div class="rating"><%= post.rating %></div> <%= link_to 'Leia na íntegra', post %> sábado, 1 de outubro de 11
  • 58. Helpers <%= image_tag('rails.png') %> <img alt="Rails" src="/images/rails.png" /> <%= stylesheet_link_tag('application') %> <link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" /> <%= javascript_include_tag('mapa') %> <script type="text/javascript" src="/javascripts/ mapa.js"></script> <% time_ago_in_words(post.created_at)%> <!-- 3 minutos atrás --> sábado, 1 de outubro de 11
  • 59. Form Helpers <%= form_for(@post) do |f| %> <div class="field"> <%= f.label :title %><br /> <%= f.text_field :title %> </div> <div class="field"> <%= f.label :body %><br /> <%= f.text_area :body %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> sábado, 1 de outubro de 11
  • 60. ActiveSupport 1.ordinalize # 1st 100.ordinalize # 100th 1.gigabyte / 512.kilobytes # 2048 1.month.from_now "author_id".humanize 3.days.ago # Author id 10.minutes.from_now "post".pluralize Time.now + 2.hours # posts date.at_beginning_of_week "primeiro evento".titleize # Primeiro Evento sábado, 1 de outubro de 11
  • 61. Perguntas? • Rails Escala? Saying “Rails doesn’t scale” is like saying “my car doesn’t go infinitely fast” - Pushion Passenger Team • Posso usar XYZ com Rails? SIM • Rails é melhor que XYZ? SIM e NÃO • Rails é bom apenas pra CRUD? NÃO e SIM • Qual o salário de programador Rails? ... • Como faço XYZ com Rails? Google! sábado, 1 de outubro de 11
  • 63. Créditos das Imagens • http://vvn.net/wp/2008/09/18/ruby-on-rails- architecture/ • Agile Web Development With Rails, 3rd Ed. • yUML.me sábado, 1 de outubro de 11