Ruby on Rails – ActiveRecord

On 8 de maio de 2015 by Bernardo Reis

Ruby on Rails

Introdução ao ActiveRecord

Neste post estudaremos ActiveRecord, uma ferramenta que permite a manipulação de dados em uma interface Ruby. Você pode pegar grupos individuais de dados de acordo com critérios específicos como ordem ou condições especiais, juntar tabelas, manipular associações, retornar listas e fazer cálculos como contagem e média. Sendo tudo isso feito no nível de banco de dados, o que é muito mais rápido que carregar os dados para sua aplicação e então manipulá-los.

O que pode ser feito com SQL pode ser feito com ActiveRecord. O que este faz é extender essa funcionalidade ao disponibilizar métodos extra que deixam a manipulação mais intuitiva e amigável.

Este tutorial é baseado no guia oficial do Ruby on Rails

Implementação ao ActiveRecord

Vamos criar um modelo utilizando ActiveRecord. Tudo que precisa ser feito é extender a classe ActiveRecord::Base.

[code language=”ruby” collapse=”false”]
class Product < ActiveRecord::Base
end
[/code]

Isso lhe permitirá fazer o seguinte tipo de manipulação:

[code language=”ruby” collapse=”false”]
p = Product.new
p.name = "Livro de exemplo"
puts p.name # "Livro de exemplo"
[/code]

A classe Product criará um modelo mapeado à tabela products no banco de dados. Caso se deseje mapear o modelo para uma tabela com outro nome, pode-se utilizar o comando:

[code language=”ruby” collapse=”false”]
class Product < ActiveRecord::Base
self.table_name = "PRODUCT"
end
[/code]

Nesse caso, será necessária a definição manual do nome da classe que provê as fixtures usando o método set_fixture_class em sua definição de teste:

[code language=”ruby” collapse=”false”]
class FunnyJoke < ActiveSupport::TestCase
set_fixture_class funny_jokes: Joke
fixtures :funny_jokes
end
[/code]

A chave primária é mapeada por convenção para a coluna ‘id’ na tabela do modelo mapeado. Caso deva-se mapear a chave primária para outra coluna da tabela, utiliza-se:

[code language=”ruby” collapse=”false”]
class Product < ActiveRecord::Base
self.primary_key = "product_id"
end
[/code]

CRUD – Create, Read, Update, Delete

Vamos utilizar o exemplo de um modelo User com os atributos name e occupation.

Create

Podemos criar um usuário da seguinte forma:

[code language=”ruby” collapse=”false”]
user = User.create(name: "Bernardo", occupation: "Desenvolvedor")
[/code]

Pode-se também utilizar o método new, que apenas intancia o objeto sem salvá-lo no banco de dados, preencher os dados e salvar o objeto preenchido no banco de dados manualmente:

[code language=”ruby” collapse=”false”]
user = User.new
user.name = "Bernardo"
user.occupation = "Desenvolvedor"
user.save
[/code]

Read

Para fazermos leitura, contamos com uma rica API do ActiveRecord para nos auxiliar. São alguns exemplos:
Retornar todos os usuários

[code language=”ruby” collapse=”false”]
users = User.all
[/code]

Retornar o primeiro e depois o último usuário

[code language=”ruby” collapse=”false”]
user = User.first

user = User.last
[/code]

Retonar o primeiro usuário com um dado nome

[code language=”ruby” collapse=”false”]
bernardo = User.find_by(name: ‘Bernardo’)
[/code]

Encontrar todos os usuários com os dados especificados e ordená-los

[code language=”ruby” collapse=”false”]
users = User.where(name: ‘Bernardo’, occupation: ‘Desenvolvedor’).order(‘created_at DESC’)
[/code]

Update

Podemos atualizar dados de forma mais extensa como:

[code language=”ruby” collapse=”false”]
user = User.find_by(name: ‘Bernardo’)
user.name = ‘Ricardo’
user.save
[/code]

Ou de forma mais enxuta:

[code language=”ruby” collapse=”false”]
user = User.find_by(name: ‘Bernardo’)
user.update(name: ‘Ricardo’)
[/code]

Para atuazliar vários dados de uma vez (nesse caso, todos os dados do banco de dados):

[code language=”ruby” collapse=”false”]
User.update_all "name = ‘Ricardo’, ocupation = ‘Professor’"
[/code]

Delete

Uma vez que um dado já foi recuperado, para destruí-lo é simples:

[code language=”ruby” collapse=”false”]
user = User.find_by(name: ‘David’)
user.destroy
[/code]

Validações

O ActiveRecord permite o uso de validações nos modelos antes que eles sejam escritos no banco de dados. Existem vários métodos de validação que podem ser usados para fazer determinadas checagem nos dados, como se o valor é nulo, único, possui ou não determinados dados em certo campo, etc.

Essas validações são consideradas pelos métodos ‘save’ e ‘update’ do ActiveRecord para que este saiba se é permitido ou não armazenar determinado dado no banco de dados. Caso esses métodos não possam realizar a persistência dos dados, eles retornam ‘false’. No caso de se utilizar os métodos ‘save!’ e ‘update!’, o retorno será uma exceção.

Vejamos um exemplo do seguinte modelo:

[code language=”ruby” collapse=”false”]
class User < ActiveRecord::Base
validates :name, presence: true
end
[/code]

A seguir o resultado da tentativa de salvar um dado inconsistente com a validação do modelo:

[code language=”ruby” collapse=”false”]
user = User.new
user.save # => false
user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can’t be blank
[/code]

Callback

Uma das disponibilidades do ActiveRecord é a adição de callback, códigos que podem ser embutidos no ciclo de vida de seu modelos e que serão executados em determinados momentos.
Um exemplo de callback pode ser capitalizar uma string (fazer com que sua primeira letra seja maiúscula). Neste exemplo, colocamos o nome do usuário como sendo seu login com a primeira letra maiúscula case ele ainda não tenha um nome definido:

[code language=”ruby” collapse=”false”]
class User < ActiveRecord::Base
validates :login, :email, presence: true

before_create do
self.name = login.capitalize if name.blank?
end
end
[/code]

Lista de Callbacks (citados em sua ordem de execução em cada método chamado):

Criação de objetos:

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_create
  • around_create
  • after_create
  • after_save
  • after_commit/after_rollback

Atualização de objetos:

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_update
  • around_update
  • after_update
  • after_save
  • after_commit/after_rollback

Destruição de objetos:

  • before_destroy
  • around_destroy
  • after_destroy
  • after_commit/after_rollback

Migrations

O ActiveRecord disponibiliza, ainda, ‘migrations’, que são utilizadas para manipular o esquema de um banco de dados. Eles são guardados em arquivos e executados em bancos de dados utilizando-se comandos ‘rake’. O Rails monitora quais arquivos já foram executados no banco de dados, permitindo assim, a funcionalidade de fazer rollbacks.

Um exemplo de Migration seria:

[code language=”ruby” collapse=”false”]
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :occupation
t.string :login
t.string :email

t.timestamps null: false
end
end
end
[/code]

Conclusão

Vimos nesse tutorial o quanto o ActiveRecord deixa amigável a manipulação de modelos em um banco de dados. Todas essas características deixam o sistema muito mais fácil de ser desenvolvido, mais enxuto e fácil de ler, o que é o objetivo do framework Rails em si.

Deixe um comentário

O seu endereço de e-mail não será publicado.