52
Ruby on Rails I Tiago Ferreira Lima - fltiago

Ruby on Rails I - Modelos

Embed Size (px)

DESCRIPTION

Uma breve apresentação explicando as funcionalidades básicas dos modelos com o ActiveRecord como ORM.

Citation preview

Page 1: Ruby on Rails I - Modelos

Ruby on Rails I

Tiago Ferreira Lima - fltiago

Page 2: Ruby on Rails I - Modelos

Roteiro

• Começando com Rails• Migrações• ActiveRecord

• Validações

• Callbacks

• Associações

• Query Interface

• Mãos à obra

Page 3: Ruby on Rails I - Modelos

Começando com Rails

Page 4: Ruby on Rails I - Modelos

O que é Rails?

• Framework para desenvolvimento de aplicações Web

• Filosofia Rails• DRY - “Don’t Repeat Yourself”

• Convenção sobre configuração

• REST

Page 5: Ruby on Rails I - Modelos

MVC

• Arquitetura de software baseada em Modelos, Views e Controladores

• Benefícios• Isolamento da lógica de negócios

• Clara separação de responsabilidades, facilitando a manutenção

Page 6: Ruby on Rails I - Modelos

Os componentes do Rails

• Action Pack• Action Controller

• Action Dispatch

• Action View

• Action Mailer

Page 7: Ruby on Rails I - Modelos

Os componentes do Rails

• Active Model• Active Record• Active Resource• Active Support• Railties

Page 8: Ruby on Rails I - Modelos

Instalando Rails

• Linux e Mac (se já houver o rubygems)

• Windows• Rails Installer FTW! http://

railsinstaller.org/

$  gem  install  rails$  rails  -­‐-­‐version

Page 9: Ruby on Rails I - Modelos

Criando uma aplicação Rails

• Um único comando$  rails  new  nome_do_app

Page 10: Ruby on Rails I - Modelos

Estrutura de uma aplicação Rails

Page 11: Ruby on Rails I - Modelos

Migrações

Page 12: Ruby on Rails I - Modelos

Migrações

• Um jeito bonito e organizado de alterar o banco de dados

• Vantagens• Não há necessidade de comunicar outros

desenvolvedores que houve mudança no BD

• Não há necessidade de conhecer a linguagem específica do SQL

• É independente de banco de dados, suporte a diversos SGBDs

Page 13: Ruby on Rails I - Modelos

Migrações

• Estrutura das migrações:class  CreateProducts  <  ActiveRecord::Migration

   def  up        create_table  :products  do  |t|            t.string  :name            t.text  :description              t.timestamps        end    end      def  down        drop_table  :products    endend

Page 14: Ruby on Rails I - Modelos

Migrações

• Ou:class  CreateProducts  <  ActiveRecord::Migration    def  change        create_table  :products  do  |t|            t.string  :name            t.text  :description              t.timestamps        end    endend

Page 15: Ruby on Rails I - Modelos

Migrações

• Olhando mais de perto as migraçõesclass  CreateProducts  <  ActiveRecord::Migration

   def  up        create_table  :products  do  |t|            t.string  :name            t.text  :description              t.timestamps        end    end      def  down        drop_table  :products    endend

Page 16: Ruby on Rails I - Modelos

Migrações

• Métodos:add_columnadd_indexadd_referenceadd_timestampscreate_tablecreate_join_tabledrop_table (must supply a block)drop_join_table (must supply a block)remove_timestampsrename_columnrename_indexremove_referencerename_table

Page 17: Ruby on Rails I - Modelos

Migrações

• Types::binary:boolean:date:datetime:decimal:float:integer:primary_key:string:text:time:timestamp

Page 18: Ruby on Rails I - Modelos

E finalmente, criando uma migração

• Com o model$  rails  generate  model  Product  name:string  description:text

#  Geraclass  CreateProducts  <  ActiveRecord::Migration    def  change        create_table  :products  do  |t|            t.string  :name            t.text  :description              t.timestamps        end    endend

Page 19: Ruby on Rails I - Modelos

E finalmente, criando uma migração

• Uma migração por si só

• Convenções facilitam a criação

$  rails  generate  migration  AddPartNumberToProducts

#  Geraclass  AddPartNumberToProducts  <  ActiveRecord::Migration    def  change    endend

$  rails  generate  migration  AddPartNumberToProducts  part_number:string

class  AddPartNumberToProducts  <  ActiveRecord::Migration    def  change        add_column  :products,  :part_number,  :string    endend

Page 20: Ruby on Rails I - Modelos

O mais importante

• Executando migrações

• Voltando uma migração

$  rake  db:migrate

$  rake  db:migrate  VERSION=20080906120000

$  rake  db:rollback

$  rake  db:rollback  STEP=3

Page 21: Ruby on Rails I - Modelos

ActiveRecord

Page 22: Ruby on Rails I - Modelos

ActiveRecord

• É a implementação de um padrão de mapeamento objeto-relacional (ORM)

• Conecta classes e atributos a tabelas e colunas

Page 23: Ruby on Rails I - Modelos

ActiveRecord

• Permite:• Migrações

• Validações

• Associações

• Callbacks

• Transações

• Entre outras coisas...

Page 24: Ruby on Rails I - Modelos

Validações

Page 25: Ruby on Rails I - Modelos

Visão geral

• Garante que apenas dados válidos serão inseridos no banco de dados

• Existem diversos meios de garantir a validação de um dado: restrições dos banco de dados, validações em client-side, validações em controladores e validações em modelo

• Vamos nos concentrar em modelos, é um jeito Rails de fazer validações

Page 26: Ruby on Rails I - Modelos

Quando uma validação acontece?

• Antes que os objetos sejam salvos no banco de dados

• Métodos que disparam validaçõescreatecreate!savesave!updateupdate_attributesupdate_attributes!

Page 27: Ruby on Rails I - Modelos

Exemplo de uso

• valid? e invalid?class  Person  <  ActiveRecord::Base    validates  :name,  :presence:  trueend  >>  p  =  Person.new=>  #<Person  id:  nil,  name:  nil>>>  p.errors=>  {}  >>  p.valid?=>  false>>  p.errors=>  {name:["can't  be  blank"]}  >>  p  =  Person.create=>  #<Person  id:  nil,  name:  nil>>>  p.errors=>  {name:["can't  be  blank"]}  >>  p.save=>  false  >>  p.save!=>  ActiveRecord::RecordInvalid:  Validation  failed:  Name  can't  be  blank

Page 28: Ruby on Rails I - Modelos

Validations Helpers

• Aceitaçãoclass  Person  <  ActiveRecord::Base    validates  :terms_of_service,  acceptance:  trueend

class  Library  <  ActiveRecord::Base    has_many  :books    validates_associated  :booksend

class  Person  <  ActiveRecord::Base    validates  :email,  confirmation:  true    validates  :email_confirmation,  presence:  trueend

• Valida modelos associados

• Confirmação e Presença

Page 29: Ruby on Rails I - Modelos

Validations Helpers

• Exclusãoclass  Account  <  ActiveRecord::Base    validates  :subdomain,  exclusion:  {  in:  %w(www  us  ca  jp),        message:  "Subdomain  %{value}  is  reserved."  }end

class  Product  <  ActiveRecord::Base    validates  :legacy_code,  format:  {  with:  /\A[a-­‐zA-­‐Z]+\z/,        message:  "Only  letters  allowed"  }end

class  Coffee  <  ActiveRecord::Base    validates  :size,  inclusion:  {  in:  %w(small  medium  large),        message:  "%{value}  is  not  a  valid  size"  }end

• Formatação

• Inclusão

Page 30: Ruby on Rails I - Modelos

Validations Helpers

• Tamanhoclass  Person  <  ActiveRecord::Base    validates  :name,  length:  {  minimum:  2,  maximum:  500  }    validates  :password,  length:  {  in:  6..20  }    validates  :registration_number,  length:  {  is:  6  }end

class  Player  <  ActiveRecord::Base    validates  :points,  numericality:  true    validates  :games_played,  numericality:  {  only_integer:  true  }end

class  Account  <  ActiveRecord::Base    validates  :email,  uniqueness:  trueend

• Numeração

• Unicidade

Page 31: Ruby on Rails I - Modelos

Callbacks

Page 32: Ruby on Rails I - Modelos

Visão Geral

• Callbacks são uma forma de associar comportamento a determinados momentos do ciclo de vida de um modelo

• É possível escrever códigos que executem sempre que um objeto do ActiveRecord é criado, salvado, atualizado, deletado, validado ou carregado do banco de dados.

Page 33: Ruby on Rails I - Modelos

Exemplos de uso

class  User  <  ActiveRecord::Base    validates  :login,  :email,  presence:  true      before_validation  :ensure_login_has_a_value      protected    def  ensure_login_has_a_value        if  login.nil?            self.login  =  email  unless  email.blank?        end    endend

class  User  <  ActiveRecord::Base    validates  :login,  :email,  presence:  true      before_create  do  |user|        user.name  =  user.login.capitalize  if  user.name.blank?    endend

Page 34: Ruby on Rails I - Modelos

Callbacks disponíveis

• Criando um objeto before_validationafter_validationbefore_savearound_savebefore_createaround_createafter_createafter_save

before_validationafter_validationbefore_savearound_savebefore_updatearound_updateafter_updateafter_save

• Atualizando um objeto

Page 35: Ruby on Rails I - Modelos

Callbacks disponíveis

• Destruindo um objetobefore_destroyaround_destroyafter_destroy

Page 36: Ruby on Rails I - Modelos

Associações

Page 37: Ruby on Rails I - Modelos

Visão Geral

• Relacionamentos/associações são parte central dos bancos de dados relacionais

• ActiveRecord facilita as interações entre modelos

Page 38: Ruby on Rails I - Modelos

Exemplo de uso

class  Customer  <  ActiveRecord::Base    has_many  :orders,  dependent:  :destroyend  class  Order  <  ActiveRecord::Base    belongs_to  :customerend

#  rails  console$  @orders  =  @customer.orders$  @costumer  =  @order.customer

Page 39: Ruby on Rails I - Modelos

Tipos de associações

• Tipos:belongs_tohas_onehas_manyhas_many :throughhas_one :throughhas_and_belongs_to_many

Page 40: Ruby on Rails I - Modelos

Query Interface

Page 41: Ruby on Rails I - Modelos

Visão Geral

• Internface que define acesso ao banco e instancia os objetos

• ActiveRecord facilita a interação entre o objeto e banco de dados

Page 42: Ruby on Rails I - Modelos

Retornando um simples objeto

• Usando a primary key (find)#  Encontra  um  client  com  id  =  10client  =  Client.find(10)#  =>  #<Client  id:  10,  first_name:  "Ryan">

#  O  SQL  gerado  por  RailsSELECT  *  FROM  clients  WHERE  (clients.id  =  10)  LIMIT  1

• Usando métodos já prontosclient  =  Client.last#  =>  #<Client  id:  221,  first_name:  "Russel">

SELECT  *  FROM  clients  ORDER  BY  clients.id  DESC  LIMIT  1

client  =  Client.first#  =>  #<Client  id:  1,  first_name:  "Lifo">

SELECT  *  FROM  clients  LIMIT  1

Page 43: Ruby on Rails I - Modelos

Retornando muitos objetos

• Usando as primary keys (find)client  =  Client.find([1,  10])  #  Or  even  Client.find(1,  10)#  =>  [#<Client  id:  1,  first_name:  "Lifo">,  #<Client  id:  10,  first_name:  "Ryan">]

SELECT  *  FROM  clients  WHERE  (clients.id  IN  (1,10))

• Retornando todos os elementos de um objeto

#  Só  existem  dois  elementos  guardados  no  bancoclients  =  Client.all#  =>  [#<Client  id:  221,  first_name:  "Russel">,  #<Client  id:  10,  first_name:  "Ryan">]  

Page 44: Ruby on Rails I - Modelos

Condições

• String puraclient  =  Client.where("orders_count  =  '2'")  #  =>  [#<Client  id:  1,  first_name:  "Lifo",  orders_count:  2>,  #<Client  id:  10,  first_name:  "Ryan",  orders_count:  2>]

SELECT  *  FROM  clients  WHERE  (clients.orders_count  =  '2')

• Passando Array como parâmetroClient.where("orders_count  =  ?",  params[:orders])Client.where("orders_count  =  ?  AND  locked  =  ?",  params[:orders],  false)Client.where("created_at  >=  :start_date  AND  created_at  <=  :end_date",    {start_date:  params[:start_date],  end_date:  params[:end_date]})

Client.where(created_at:  (params[:start_date].to_date)..(params[:end_date].to_date))

SELECT  "clients".*  FROM  "clients"  WHERE  ("clients"."created_at"  BETWEEN  '2010-­‐09-­‐29'  AND  '2010-­‐11-­‐30')

Page 45: Ruby on Rails I - Modelos

Ordem e Seleção

• OrdemClient.order("created_at  DESC")#  ouClient.order("created_at  ASC")

Client.order("orders_count  ASC,  created_at  DESC")

• Seleção de colunaClient.select("viewable_by,  locked")

SELECT  viewable_by,  locked  FROM  clients

Page 46: Ruby on Rails I - Modelos

Limite e Offset

• Limite e OffsetClient.limit(5).offset(30)

SELECT  *  FROM  clients  LIMIT  5  OFFSET  30

Page 47: Ruby on Rails I - Modelos

Mãos à obra

Page 48: Ruby on Rails I - Modelos

Caso de uso

• O usuário, possui nome, e-mail, sobrenome, idade

• O usuário não existe sem nome e e-mail

• O e-mail deve ser formatado de maneira correta

• Um usuário possui vários livros

Page 49: Ruby on Rails I - Modelos

Caso de uso

• O livro deve ter nome e pode ter edição

• Os livros não existem sem os usuários

• Deve ser possível consultar os 5 livros mais recentes de um usuário

• Deve ser possível procurar usuários por nome e sobrenome

Page 50: Ruby on Rails I - Modelos

Caso de uso

• Deverá ser possível procurar por usuário entre um determinado intervalo de idade

Page 51: Ruby on Rails I - Modelos

Referências

• Rails Guides - http://guides.rubyonrails.org/

• Ruby on Rails 3 Tutorial - http://ruby.railstutorial.org/

• Design Patterns in Ruby - Russ Olsen

Page 52: Ruby on Rails I - Modelos

Obrigado!