Arquivos da Categoria: Metodologia

Associações – ActiveRecord

Este guia aborda as características de associação do ActiveRecord. Ao fazer referência a este guia, você será capaz de:

· Declarar associações entre os Models do ActiveRecord.

· Compreender os diferentes tipos de associações do ActiveRecord.

· Utilizar os métodos adicionados aos seus modelos através das associações criadas.

1. Associações, Por quê?

Por que precisamos de associações entre os modelos? Porque tornam mais fácil e mais simples operações comuns no código. Considere, por exemplo, uma simples aplicação Rails que inclui um modelo para os clientes e um modelo para as encomendas. Cada cliente pode ter muitas encomendas. Sem as associações, os modelos de declarações seriam mais ou menos assim:

class Customer < ActiveRecord::Base
end

class Order < ActiveRecord::Base
end

Agora, suponha se quisesse acrescentar uma nova encomenda de um cliente existente. Gostaríamos de fazer algo parecido com isto:

@order = Order.create(:order_date => Time.now, :customer_id => @customer.id)

Ou apagar um cliente, e garantindo que todas as suas ordens fossem excluídas também:

@orders = Order.find_by_customer_id(@customer.id)
@orders.each do |order|
  order.destroy
end
@customer.destroy

Com as associações do ActiveRecord, que podemos simplificar – e outras – operações por declarações dizendo que existe uma conexão entre os dois modelos. Veja abaixo o código revisado para a criação de clientes e encomendas:

class Customer < ActiveRecord::Base
  has_many :orders
end

class Order < ActiveRecord::Base
  belongs_to :customer
end

Com essa mudança, criando uma nova ordem para um determinado cliente é mais fácil:

@order = @customer.orders.create(:order_date => Time.now)

Excluindo um cliente e todas as suas encomendas é muito mais fácil:

@customer.destroy

Para saber mais sobre os diferentes tipos de associações, leia a próxima seção deste Guia. Seguido por alguns truques e dicas para trabalhar com as associações e, em seguida, por uma referência completa para os métodos e opções para as associações em Rails.

2. Os tipos de associações

Em Rails, uma associação é uma conexão entre os dois modelos do ActiveRecord. As associações são implementadas usando macro de chamadas, de modo que você pode adicionar funcionalidades nos seus modelos. Por exemplo, declarando que um modelo possui belongs_to com outro, você instrui o Rails a manter as informações de Chave Primária entre instâncias dos dois modelos, e você também receberá um número métodos úteis adicionado ao seu modelo. Rails suporta seis tipos de associação:

* belongs_to 

* has_one 

* has_many 

* has_many :through 

* has_one :through 

* has_and_belongs_to_many

No restante deste guia, você aprenderá a declarar e utilizar as diversas formas de associações. Mas, primeiro, uma introdução rápida a situações em que cada tipo de associação é adequado.

2.1. A Associação belongs_to

Uma associação belongs_to cria uma conexão um-para-um com outro modelo, de modo a que cada instância do modelo com a declaração “pertence a” uma instancia de um outro modelo. Por exemplo, se sua aplicação incluir clientes e encomendas, e cada encomenda pode ser atribuído por exatamente um cliente, você declararia o modelo desta forma:

class Order < ActiveRecord::Base
  belongs_to :customer
end

clip_image002[5]

2.2. A Associação has_one

A associação has_one também prevê a criação de uma conexão um-para-um com outro modelo, mas com uma semântica um pouco diferente (e conseqüências). Esta associação indica que cada instância de um modelo contém ou possui uma instancia de outro modelo. Por exemplo, se cada um fornecedor na sua aplicação possui somente uma conta, você iria declarar o modelo fornecedor como este:

class Supplier < ActiveRecord::Base
  has_one :account
end

clip_image004[5]

2.3. A Associação has_many

Uma associação has_many indica uma conexão um-para-muitos com outro modelo. Você irá encontrar muitas vezes esta associação do “outro lado” de uma associação belongs_to. Esta associação indica que cada instância do modelo possui nenhuma ou mais instancias do outro modelo. Por exemplo, em uma aplicação contendo clientes e encomendas, o modelo cliente deve ser declarado como este:

class Customer < ActiveRecord::Base
  has_many :orders
end

clip_image006[6]

O nome do outro modelo é pluralizado quando declarado uma associação has_many.

clip_image008[5]

2.4. A Associação has_many :through

Um associação has_many :through é freqüentemente utilizado para criar um conexão muitos-para-muitos com outro modelo. Esta associação indica que a declaração do modelo possa ser compensada com zero ou mais instancias de outro modelo “através de” um processo de um terceiro modelo. Por exemplo, considere uma prática médica onde pacientes podem marcar para ver médicos. As declarações relevantes da associação devem ser semelhantes a este:

class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, :through => :appointments
end

class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient
end

class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, :through => :appointments
end

clip_image010[5]

O associação has_many :through é também útil para a criação de “atalhos” através de associações has_many aninhadas. Por exemplo, se um documento tem muitas seções, e uma seção possui muitos parágrafos, você pode algumas vezes pegar uma simples coleção de todos os parágrafos no documento. Você poderia declarar desta forma:

class Document < ActiveRecord::Base
  has_many :sections
  has_many :paragraphs, :through => :sections
end

class Section < ActiveRecord::Base
  belongs_to :document
  has_many :paragraphs
end

class Paragraph < ActiveRecord::Base
  belongs_to :section
end
2.5. A Associação has_one: through

Uma associação has_one :through cria uma conexão de um-para-um com outro modelo. Esta associação indica que a declaração do modelo possa ser combinada com uma instancia de outro modelo através de um terceiro modelo. Por exemplo, se cada fornecedor possui uma conta, e cada conta está associada a um histórico da conta, então o modelo cliente poderá ser declarado desta forma:

class Supplier < ActiveRecord::Base
  has_one :account
  has_one :account_history, :through => :account
end

class Account < ActiveRecord::Base
  belongs_to :supplier
  has_one :account_history
end

class AccountHistory < ActiveRecord::Base
  belongs_to :account
end

clip_image012[5]

2.6. A Associação has_and_belongs_to_many

Uma associação has_and_belongs_to_many cria uma conexão direta muitos-para-muitos com outro modelo, sem intervir no modelo. Por exemplo, se a sua aplicação incluir peças e conjuntos, onde cada conjunto inclui várias peças e que cada peça aparece em muitos conjuntos, você poderia declarar os modelos desta maneira:

class Assembly < ActiveRecord::Base
  has_and_belongs_to_many :parts
end

class Part < ActiveRecord::Base
  has_and_belongs_to_many :assemblies
end

clip_image014[7]

2.7. Escolhendo Entre belongs_to e has_one

Se você deseja criar uma relação 1×1 entre dois modelos, será necessário adicionar a um belongs_to e ao outro has_one. Como você sabe quem é quem?

A distinção está no lugar onde você colocou a chave estrangeira (ele fica na tabela da classe que foi declarada a associação belongs_to), mas você deveria refletir um pouco mais sobre o real significado desses dados. O relacionamento has_one fala alguma coisa para os seus – ou seja, algo que aponta de volta para você. Por exemplo, faz mais sentido dizer que um fornecedor possui uma conta do que uma conta que possui um fornecedor. Isso sugere que o relacionamento correto é algo como este:

class Supplier < ActiveRecord::Base
  has_one :account
end

class Account &lt; ActiveRecord::Base
  belongs_to :supplier
end

A migração correspondente se parece com isso:

class CreateSuppliers < ActiveRecord::Migration
  def self.up
    create_table :suppliers do |t|
      t.string  :name
      t.timestamps
    end

    create_table :accounts do |t|
      t.integer :supplier_id
      t.string  :account_number
      t.timestamps
    end
  end

  def self.down
    drop_table :accounts
    drop_table :suppliers
  end
end

clip_image006[7]

Usando t.integer :supplier_id faz a nomeação da chave estrangeira óbvia e implicitamente. Nas versões atuais do Rails, você pode abstrair a implementação deste detalhe usando t.references :supplier.

2.8. Escolhendo Entre has_many :through e has_and_belongs_to_many

Rails oferece duas maneiras diferentes para declarar um relacionamento um-para-muitos entre modelos. A maneira mais simples é usar has_and_belongs_to_many, que permite que você faça a associação diretamente:

class Assembly < ActiveRecord::Base
  has_and_belongs_to_many :parts
end

class Part < ActiveRecord::Base
  has_and_belongs_to_many :assemblies
end

A segunda forma de declarar o relacionamento muitos-para-muitos é usar has_many :through. Isto faz com que crie uma associação indiretamente, através de um join no modelo:

class Assembly < ActiveRecord::Base
  has_many :manifests
  has_many :parts, :through => :manifests
end

class Manifest < ActiveRecord::Base
  belongs_to :assembly
  belongs_to :part
end

class Part < ActiveRecord::Base
  has_many :manifests
  has_many :assemblies, :through => :manifests
end

A regra é simples, você deve criar um relacionamento has_many :through se você precisa trabalhar com o relacionamento do modelo como uma entidade independente. Se você não precisa fazer nada com relacionamento do modelo, pode ser mais simples se criar um relacionamento has_and_belongs_to_many (mas você precisa se lembrar se precisa criar joins nas tabelas).

Você deve usar has_many :through se você precisar de validações, callbacks (chamadas), ou atributos extras no join do modelo.

2.9. Associações polimórficas

Um pouco mais avançado é o twist em associações polimórficas. Com associações Polimórficas, um modelo pode pertencer a mais de um modelo, em uma única associação. Por exemplo, imagine que você possa ter um modelo foto que pertence a um empregado ou ao modelo produto. Veja como isso poderia ser declarada:

class Picture < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
end

class Employee < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end

Você pode pensar em uma declaração belongs_to polimórfica criando uma interface que pode ser usada por qualquer outro modelo. A partir de uma instância do modelo Employee, você pode recuperar uma coleção de fotos: @employee.pictures. Da mesma forma, você pode usar @product.pictures. Se você tem uma instancia do modelo Picture você pode pegar seu pai através @picture.imageable. Para que isto funcione, você necessita declarar tanto uma coluna chave estrangeira e uma coluna tipo no modelo declarado com uma interface polimórficas:

class CreatePictures < ActiveRecord::Migration
  def self.up
    create_table :pictures do |t|
      t.string  :name
      t.integer :imageable_id
      t.string  :imageable_type
      t.timestamps
    end
  end

  def self.down
    drop_table :pictures
  end
end

Esta migração pode ser simplificada utilizando o formulário t.references:

class CreatePictures < ActiveRecord::Migration
  def self.up
    create_table :pictures do |t|
      t.string  :name
      t.references :imageable, :polymorphic => true
      t.timestamps
    end
  end

  def self.down
    drop_table :pictures
  end
end

clip_image016[9]

2.10. Self Joins

Na criação de um modelo de dados, às vezes você irá encontrar um modelo que deverá ter uma relação a si própria. Por exemplo, você pode armazenar todos os empregados em uma única base de dados, mas ser capaz de rastrear relacionamentos como gerentes e subordinados. Esta situação pode ser modelada com as associações com ele mesmo:

class Employee < ActiveRecord::Base
  has_many :subordinates, :class_name => "User", :foreign_key => "manager_id"
  belongs_to :manager, :class_name => "User"
end

Com essa configuração, você pode utilizar @employee.subordinates e @employee.manager.

Créditos:

Link Conteúdo Original: http://guides.rails.info/association_basics.html

Tradução: Herminio Torres. [ http://hidenowt.wordpress.com ]

Revisão: Cairo Noleto. [ http://www.caironoleto.com ]

O que é CearáOnRails?

O CearáOnRails é um evento solidário que tem como tema o desenvolvimento de sistemas web e pretende divulgar e popularizar a linguagem de desenvolvimento Ruby e o Framework Rails no estado do Ceará. Esta iniciativa contribuirá de modo relevante para promover o uso e a difusão das tecnologias entre pessoas, especialmente profissionais na área e afins, servindo como um veículo de integração, interação e colaboração. Tanto o ruby como o Rails vem mudando a forma de desenvolvimento padrão adotada pelas demais tecnologias. A linguagem Ruby foi criada em 1993 no Japão pelo Yukihiro Matsumoto. Esta só se tornou popular após a primeira apresentação do Framework Rails em 2003 criado por David Heinemeir Hansson, a sua apresentação foi bastante polêmica e mudou a visão sobre a metodologia de desenvolvimento de software. O nosso intuito é apresentar esta nova forma de desenvolver software e quanto ela é poderosa, rápida e produtiva. Com isso tentar mudar a visão atual de desenvolvimento de software na região, ou a implantação dessa nova tecnologia.

O ingresso será de 2kgs de alimentos não perecíveis por pessoa (exceto sal) em troca do acesso às palestras. Iremos doar os alimentos arrecadados para a ONG 2A(Acreditando e Aprendendo). O evento além de sua função social e integradora, também permite uma grande difusão da tecnologia e ainda oportuniza o network entre profissionais, estudantes, professores entre outros, que irão comparecer ao evento.

Organizadores do CearaOnRails

Os abaixo indicados subscrevem essa proposta, considerando-se responsáveis pelo evento:

  • Herminio Cesar Muniz Torres, Programador Júnior da Oktiva.

Telefone: (85) – 8884.8466 / E-mail: herminiocesar@gmail.com

  • Ítalo Matos Cavalcante Santos, Analista de Sistemas da Active Brasil.

Telefone: (85) – 8867.0055 / E-mail: italomatos@gmail.com

  • Rafael Cruz Rubert, Programador Júnior da RJ contabilidade.

Telefone: (85) – 8830.3547 / E-mail: rafarubert@yahoo.com.br

  • Victor Sobreira, Programador Júnior da Itarget.

Telefone: (85) – 8719.3391 / E-mail: victorcsv@gmail.com

Realização do CearaOnRails

O evento será realizado no dia 14 de Novembro de 2008 das 19:00 às 22:30 horas. Na Faculdade Christus, Avenida Dom Luís, 911, Fortaleza-Ce, no 15º Andar, em Fortaleza-Ceará. A programação prévia estabelecida pela organização será a seguinte:

19:00-19:10 Abertura

19:10-19:40 Palestra 1

Palestrante: Tiago Bastos

Tema: Onde está o método?

Descrição: Uma introdução a recursos avançados da linguagem. Explicando como interceptar chamadas à métodos, monkey patching e avaliação de código. Mercado de trabalho.

19:40-20:40 Palestra 2

Palestrante: Nabucodonosor Coutinho

Tema: ORM On Rails

Descrição: A camada de persistência do ROR está realmente nos trilhos? A visão de um DBA sobre a camada de persistência do Rails. Analise dos padrões DAO e ActiveRecord. Análise das implementações ActiveRecord e iBatis para Ruby. Análise das implementações Rails ActiveRecord e Hibernate (java).

20:40-21:00 Coffee Break

21:00-22:00 Palestra 3

Palestrante: Fábio Akita

Tema: Desenvolvimento fora da Média com Ruby e Rails

Descrição: Porque é importante entender as novas tecnologias como Ruby e Rails e como elas agilizam seus projetos web.

22:00-22:10 Encerramento e Sorteio de brindes[Livros e Camisetas]

Maiores informações: http://www.cearaonrails.org

Inicialmente eu comecei lendo o tutorialruby tentando entender sem ao menos digitar nenhuma linha de código para treino como se eu fosse um “compilador”, li ele até a pagina 65, porque as demais eu li e estou voando, então eu decidi pegar algo mais simples e iniciar novamente o aprendizado então achei dois tutoriais super simples para começar. Inicialmente vou está estudando pelo aprendaaprogramar, e logo após estarei partindo para o pequenolivroruby. O aprendaaprogramar é ótimo para aprender ruby estruturado e o aprendaaprogramar é melhor para a programação orientada a objeto e em paralelo aos dois estarei lendo o livro Getting Real traduzido pelo Fabio Akita, e quando termina essas leitura retornarei para a apostila do Taq. E para quem entende inglês uma boa pedida é noobkit é um site onde bem estruturado onde você pode navegar dentro da documentação/api tanto de ruby como rails e gems.