Introdução a ActiveRecord no Rails

Veja nesse artigo uma introdução ao módulo ActiveRecord do framework Ruby on Rails, apresentando os métodos de manipulação de registros em bancos de dados.

O ActiveRecord é uma espécie de ORM (Object Relation Mapping), isto significa que ele é responsável por mapear classes da aplicação para tabelas do banco de dados. Esse módulo representa o Modelo na arquitetura Model, View e Control, que é responsável pela lógica do sistema e pela representação de dados. Além disso, ele facilita a manipulação de objetos persistentes de uma tabela, sem que o desenvolvedor escreva uma linha de SQL sequer. Além disso, ele também fornece recursos para que um modelo seja validado antes de ser persistido em uma base de dados. Isso tudo escrevendo pouca ou nenhuma configuração, já que o framework Rails favorece a convenção sob a configuração.

A fim de seguir os exemplos apresentados durante esse artigo, é necessário que o leitor possua o Ruby e o Rails instalado na sua máquina. O tópico seguinte dá uma explicação rápida de como configurar o ambiente de desenvolvimento nos sistemas operacionais mais comumente usados.

Instalação

O primeiro passo para a configuração do ambiente é a instalação ao Ruby. Para ambiente Debian ou Ubuntu o comando apresentado a seguir deverá ser executado no terminal.

sudo apt-get install ruby-full

Já para ambientes como os sistemas operacionais Fedora e CentOS, o comando de instalação será semelhante ao mostrado a seguir:

sudo yum install ruby

Após o término da instalação da linguagem é possível ver se tudo aconteceu corretamente executando o comando apresentado a seguir, que deve retornar a impressão da versão da linguagem:

ruby --version ruby 2.1.5p273 (2014-11-13) [x86_64-linux-gnu]

ou apenas

ruby -v ruby 2.1.5p273 (2014-11-13) [x86_64-linux-gnu]

O passo seguinte é instalar o framework Rails, que nada mais é do que uma gem (semelhantes aos .jar's do Java) ou biblioteca. Utilize o comando a seguir para instalação do framework:

gem install rails

Para o sistema operacional Windows as ferramentas RubyInstaller e RailsInstaller facilitam a configuração do ambiente, então basta fazer o download da versão desejada e seguir a instalação padrão apresentada no setup.

Classes Modelos

As classes que representam a camada de negócio de uma aplicação Rails ficam localizadas no diretório app/models, que é gerado automaticamente durante a criação da aplicação. Para que uma classe tenha acesso aos recursos que o ActiveRecord fornece é necessário que ela estenda a classe Base desse módulo como mostra o código a seguir:

class Produto < ActiveRecord::Base end

O framework automaticamente associaria essa classe com uma tabela no banco de dados chamada produtos e todas as colunas dela funcionariam como atributos de instância da classe Produto. Isso será explanado com exemplos logo a frente.

Criação de Aplicação para Exemplos

Para executar alguns testes com o ActiveRecord essa sessão apresenta a criação de uma aplicação de exemplo. Começaremos com a escolha de um diretório: navegue até ele pelo terminal ou prompt de comando e depois de acessado basta digitar o comando apresentado a seguir:

~/RailsProjects$ rails new testes_rails

Esse comando faz uso do gerador do framework para construir toda a estrutura inicial da aplicação.

O resultado da execução desse comando deve ser semelhante a saída apresentada na Listagem 1.

Listagem 1. Saída ou resultado do comando de criação da aplicação.

create create README.rdoc create Rakefile create config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/views/layouts/application.html.erb create app/assets/images/.keep create app/mailers/.keep create app/models/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep […] run bundle install Resolving dependencies... Bundle complete! 12 Gemfile dependencies, 54 gems now installed.

Criação do Primeiro Modelo

Agora já é possível construir uma classe de modelo e conectá-la a uma tabela no banco de dados. Para isso basta criar um arquivo dentro do diretório app/models com o nome da classe que desejar.

Existem alguns detalhes importantes para lembrar referente a nomenclaturas:

O código a seguir apresenta a criação de um modelo na aplicação de exemplo construída anteriormente:

class Usuario < ActiveRecord::Base end

Note que não há nada de extraordinário nela, apenas uma classe que estende de ActiveRecord::Base, que tem por objetivo estar associada ou representar uma tabela do banco de dados.

A classe Usuario não está (pelo menos ainda não) ligada a nenhuma estrutura do banco. Para fazer essa ligação basta criar uma tabela seguindo as convenções de nomeação do Rails. O framework vai pluralizar o nome de classe e procurar na base de dados uma relação com esse nome no plural. Isso significa que a tabela correspondente a classe Usuario teria o nome usuarios.

Porém, antes de criar essa tabela é importante atentar para um detalhe: o framework Rails vai pluralizar o nome das classes de acordo com as regras do idioma inglês, por exemplo a palavra “autor” seria pluralizada como “autors” e não “autores”, ou “qualificação” seria pluralizada como “qualificaçãos” e não “qualificações”.

É possível dizer ao Rails como ele deve pluralizar as palavras por meio do arquivo config/initializers/inflections.rb. Veja no bloco de código apresentado na Listagem 2 a mudança dessa regra para as palavras “autor” e “qualificação” que citamos. Perceba que para isso apenas é necessário passar a palavra no singular seguida de como se deseja pluralizar para o método inflect.irregular.

Listagem 2. Alteração da pluralização das palavras “autor” e “qualificacao”.

ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.irregular 'qualificacao', 'qualificacoes' inflect.irregular 'autor', 'autores' end

No caso da classe Usuario não será necessário alterar a regra de pluralização, então para ligar essa classe à base de dados basta simplesmente criar uma tabela chamada usuarios.

Antes disso precisamos que a aplicação tenha um banco de dados e o código a seguir apresenta o comando Rails para essa tarefa:

~/RailsProjects/testes_rails$ rake db:create

Note que esse comando deve ser executado dentro do diretório da aplicação e ele não imprimirá nada no terminal.

A fim de que o desenvolvedor possa alterar as estruturas do banco de dados da aplicação, o Rails oferece um console que permite manipulá-lo. Para isso basta digitar o comando rails dbconsole dentro do diretório da aplicação. Nesse console é possível executar comandos SQL para fazer consultas na base da aplicação ou para modificar a sua estrutura (criando, excluindo ou alterando tabelas).

Para seguir com os exemplos vamos criar uma tabela chamada usuarios e o Rails automaticamente vai associá-la com a classe Usuario que foi criada. Veja na Listagem 3 o código de criação para essa tabela.

Listagem 3. Código SQL de criação da tabela usuarios executado pelo dbconsole do Rails.

sqlite> CREATE TABLE usuarios( ...> id INTEGER PRIMARY KEY AUTOINCREMENT, ...> nome varchar(70), ...> email varchar(70), ...> login varchar(30), ...> senha varchar(10) ...> );

Após a tabela criada a classe Usuario já está conectada a tabela usuarios. É possível comprovar isso acessando o Rails console, que simula a aplicação sendo executada. Para acessá-lo basta digitar no terminal o comando rails console. Ele permite executar o código ruby inclusive fazendo operações com o banco de dados da aplicação.

Veja na Listagem 4 que a classe usuario, após a criação de sua respectiva tabela, já possui os métodos para recuperar (get's) e modificar (set's) atributos com os mesmos nomes das colunas.

Listagem 4. Uso dos métodos para recuperar e modificar atributos da classe Usuario.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> usuario1 = Usuario.new irb(main):002:0> usuario1.nome = "João da Silva" => "João da Silva" irb(main):003:0> usuario1.email = "joao@silva.com" => "joao@silva.com" irb(main):004:0> usuario1.login = "joao.silva" irb(main):005:0> usuario1.senha = "12345" => "12345" irb(main):006:0> puts "#{usuario1.nome} - #{usuario1.email}" =>João da Silva – joao@silva.com

Métodos disponíveis no ActiveRecord

Quando uma classe estende ActiveRecord::Base muitos recursos ficam disponíveis, inclusive métodos para persistência, consulta e alterações de informações no banco de dados. Usaremos o rails console para testar alguns dos principais métodos disponíveis.

Save

Esse método salva ou persiste o objeto no banco de dados. Veja no bloco de código apresentado na Listagem 5 o preenchimento dos dados de um usuário e em seguida o uso do método save para armazenar o objeto no banco. Note que ao final o método retornou true, indicando que o objeto foi persistido com sucesso.

Listagem 5. Exemplo de uso do método save.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> usuario1 = Usuario.new irb(main):002:0> usuario1.nome = "José da Silva Leite" => "José da Silva Leite" irb(main):003:0> email = "jose@silva_leite.com" => "jose@silva_leite.com" irb(main):004:0> usuario1.login = "jose.silva" => "jose.silva" irb(main):005:0> usuario1.senha = "12345" => "12345" irb(main):006:0> usuario1.save =>true

Perceba que nenhuma linha de SQL foi necessária para inserir os dados do objeto no banco de dados, pois o método save faz esse trabalho pelo desenvolvedor. Veja na Listagem 6 o comando SQL que a chamada ao método save gerou.

Listagem 6. SQL gerado pela chamada ao método save.

(0.3ms) begin transaction SQL (18.3ms) INSERT INTO "usuarios" ("nome", "email", "login", "senha") VALUES (?, ?, ?) [["nome", "José da Silva Leite"], ["email", "jose@silva_leite.com"], ["login", "jose.silva"], ["senha", "12345"]] (75.1ms) commit transaction

Create

É possível instanciar um objeto e automaticamente persisti-lo no banco de dados com o método create. Ele recebe um hash com o nome do atributo seguido do valor correspondente e salva o objeto no banco. Veja a seguir a sintaxe de chamada do método:

NomeDaClasse.create(atributo1: “valor1”, atributo2: “valor2”, atributo3: “valor3”)

Em seguida note o exemplo de uso desse método na Listagem 7.

Listagem 7. Exemplo de uso do método create.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> Usuario.create(nome: "Silva Souza Oliveira", email: "silva@souza_oliveira.com", login: "silva.souza", senha: "12345") (0.2ms) begin transaction

O código SQL equivalente é:

SQL (0.5ms) INSERT INTO "usuarios" ("nome", "email", "login", "senha") VALUES (?, ?, ?, ?) [["nome", "Silva Souza Oliveira"], ["email", "silva@souza_oliveira.com"], ["login", "silva.souza"], ["senha", "12345"]] (104.6ms) commit transaction

All

Esse método recupera todos os registros de uma tabela. Veja na Listagem 8 o seu uso para mostrar o nome seguido do e-mail de cada um dos usuários que já estão armazenados na tabela.

Listagem 8. Uso do método all para mostrar o nome e o e-mail dos usuários cadastrados.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> Usuario.all.each do |u| irb(main):002:1* puts "#{u.nome} - #{u.email}" irb(main):003:1> end

O código SQL equivalente é:

Usuario Load (1.9ms) SELECT "usuarios".* FROM "usuarios" José da Silva Leite - jose@silva_leite.com Silva Souza Oliveira - silva@souza_oliveira.com Soares da Silva Souza – soares@silva_souza.com

First e Last

Esses métodos quando chamados sem parâmetro retornam o primeiro e o último registro encontrado na tabela, respectivamente, conforme mostra a Listagem 9.

Listagem 9. Uso dos métodos first e last.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> Usuario.first

O código SQL equivalente é:

Usuario Load (0.2ms) SELECT "usuarios".* FROM "usuarios" ORDER BY "usuarios"."id" ASC LIMIT 1 => #<Usuario id: 1, nome: "José da Silva Leite", email: nil, login: "jose.silva", senha: "12345"> irb(main):002:0> Usuario.last Usuario Load (0.2ms) SELECT "usuarios".* FROM "usuarios" ORDER BY "usuarios"."id" DESC LIMIT 1 => #<Usuario id: 3, nome: "Soares da Silva Souza", email: "soares@silva_souza.com", login: "soares.silva", senha: "12345">

Também é possível passar um parâmetro para esses métodos informando quantos registros devem ser recuperados. Por exemplo, Usuario.first(3) retornaria os três primeiros usuários e Usuario.last(3) os três últimos registros.

Find_by

Esse método retorna o primeiro registro em que os valores dos atributos são idênticos aos passados nos parâmetros. Por exemplo, a Listagem 10 procura por um usuário com login igual à “jose.silva”.

Listagem 10. Uso do método find_by para buscar um usuário pelo login.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> Usuario.find_by(login: "jose.silva")

O código SQL equivalente é:

Usuario Load (0.4ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."login" = ? LIMIT 1 [["login", "jose.silva"]] => #<Usuario id: 1, nome: "José da Silva Leite", email: nil, login: "jose.silva", senha: "12345">

Update

Esse método atualiza um ou múltiplos objetos no banco de dados. Para atualizar um único registro basta passar como parâmetro o identificador, seguido dos atributos que se deseja atualizar, como mostra o exemplo da Listagem 11. Note que antes e depois da atualização os dados são mostrados para que se comprove a alteração.

Listagem 11. Exemplo de uso do método update para atualizar um único registro.

~/RailsProjects/testes_rails$ rails console irb(main):001:0> usuario = Usuario.find_by(id: 1) Usuario Load (0.3ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = ? LIMIT 1 [["id", 1]] irb(main):002:0> puts "#{usuario.login} - #{usuario.senha}" =>jose.silva - 12345 irb(main):003:0> Usuario.update(1, login: "jose.silva.leite", senha: "54321")

O código SQL equivalente é:

Usuario Load (0.3ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = ? LIMIT 1 [["id", 1]] (0.3ms) begin transaction SQL (0.6ms) UPDATE "usuarios" SET "login" = ?, "senha" = ? WHERE "usuarios"."id" = ? [["login", "jose.silva.leite"], ["senha", "54321"], ["id", 1]] (357.3ms) commit transaction irb(main):004:0> usuario = Usuario.find_by(id: 1) Usuario Load (0.2ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = ? LIMIT 1 [["id", 1]] irb(main):005:0> puts "#{usuario.login} - #{usuario.senha}" jose.silva.leite – 54321

O método update também pode ser usado para atualizar múltiplos registros. Para isso é necessário passar dois hash's: o primeiro contendo os identificadores e o segundo contendo os atributos e seus respectivos valores para alteração, como mostra o exemplo da Listagem 12.

Listagem 12. Uso do método update para atualizar múltiplos registros.

~/RailsProjects/testes_rails$ rails console irb(main):001:0> usuarios = {1 => {nome: "souza da silva"}, 2 => {nome: "antonio oliveira"}} irb(main):002:0> Usuario.update(usuarios.keys, usuarios.values)

O código SQL equivalente é

Usuario Load (0.3ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = ? LIMIT 1 [["id", 1]] (0.2ms) begin transaction SQL (0.4ms) UPDATE "usuarios" SET "nome" = ? WHERE "usuarios"."id" = ? [["nome", "souza da silva"], ["id", 1]] (372.0ms) commit transaction Usuario Load (0.3ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = ? LIMIT 1 [["id", 2]] (0.1ms) begin transaction SQL (0.3ms) UPDATE "usuarios" SET "nome" = ? WHERE "usuarios"."id" = ? [["nome", "antonio oliveira"], ["id", 2]] (62.0ms) commit transaction

Destroy

Esse método remove do banco de dados o objeto que foi chamado. Veja na Listagem 13 um exemplo de uso do mesmo.

Listagem 13. Exemplo de uso do método destroy.

~/RailsProjects/testes_rails$ rails console Loading development environment (Rails 4.2.4) irb(main):001:0> usuario = Usuario.find_by(id: 1)

O código SQL equivalente é:

Usuario Load (0.4ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = ? LIMIT 1 [["id", 1]] => #<Usuario id: 1, nome: "souza da silva", email: nil, login: "jose.silva.leite", senha: "54321"> irb(main):002:0> usuario.destroy (0.3ms) begin transaction SQL (0.6ms) DELETE FROM "usuarios" WHERE "usuarios"."id" = ? [["id", 1]] (85.5ms) commit transaction

Viu como é fácil trabalhar com o Active Record no ruby? Ele auxiliou muito na rapidez da geração de código, pois foram poucos comandos para muito código SQL, que acompanhamos nas listagens.

Referências

RailsGuides
http://guides.rubyonrails.org/active_record_basics.html

API Dock
http://apidock.com/rails/ActiveRecord/Base

API Ruby On Rails
http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados