Nesta aula iremos aprender a diferença de fazer um modelo de forma manual e a agilidade que teremos criando um modelo com migrations.
Nesta aula falaremos sobre:
Nós criaremos os modelos de forma manual e através dos migrations para ver o comportamento a fundo.
Lembre-se de entrar no diretório que criamos a primeira aplicação na aula passada.
Començado, para gerar um banco de dados:
rake db:create
Ou caso precise fazer pelo bundle:
bundle exec rake db:create
Assim criamos um bando de desenvolvimento e o de teste é gerado automaticamente também.
Abra um gerenciador de banco de dados como o MySQL Workbench, crie uma tabela chamada produtos1
seguindo as configurações da aula caso use o MySQL, ou adapte para o seu banco.
Agora na pasta app/models
criaremos um model(modelo) chamado produto.rb
, para interação com nosso banco de dados.
class Produto
def initialize(attrs=nil)
if attrs.present?
self.id = arrts["id"]
self.nome = arrts["nome"]
end
end
attr_accessor :id, :nome
def self.buscar
produtos = ActiveRecord::Base.connection.exec_query("select * from produtos1")
return produtos.map{|p| Produto.new(p)}
end
end
No código acima fizemos uma classe para acessar nossos dados através do Rails, assim fazemos um attr_accessor
, que já provê métodos get e set para nós, um método buscar
junto com o self para executar na mesma instância, além do ActiveRecord
, que é nosso intermediário entre o Rails e o Banco de dados SQL, armazenamos o resultado dessa consulta que busca todos dados da tabela na variável produtos
, retornamos a variável produtos
, ela recebe os dados mapeados no caso id e nome, observe o construtor recebendo os argumentos no método initialize
.
Utilizaremos o home_controller que fizemos na aula passada para testar nosso model.
Alteramos o código dentro da classe para:
@produtos = Produto.buscar
Precisamos fazer a view exibir os dados agora, em app/views/home/index.html.rb
faça:
<% produtos.each do |produto| %>
-
ID: <% produto.id %>
NOME: <% produto.nome %>
<% end %>
Caso tenha cadastrado algum dado no banco já deve aparecer aqui, mas vamos criar nossos métodos para isso.
Agora voltamos para o arquivo produto.rb
faremos um método para criação/create ou seja salvar dados no banco:
def salvar
ActiveRecord::Base.connection.execute("insert into produtos1 (nome) values ('#{self.nome}');")
end
Para fazer uma atualização/update:
def atualizar
ActiveRecord::Base.connection.execute("update produtos1 set nome = '#{self.nome}') where = id = '#{self.id}');")
end
Para fazer uma exclusão/delete:
def excluir
ActiveRecord::Base.connection.execute("delete from produtos1 where = id = '#{self.id}');")
end
Podemos testar nossos métodos com o controller, o arquivo produto.rb
dentro de index
deve ter dados novos quanto atualizar a página.
produto = Produto.new
produto.id = 4
produto.exluir
Criar:
produto = Produto.new
produto.nome = "José"
produto.salvar
@produtos = Produto.buscar
Atualizar:
produto = Produto.new
produto.id = 4
produto.nome = "José ---"
produto.atualizar
@produtos = Produto.buscar
Exluir:
produto = Produto.new
produto.id = 4
produto.exluir
Agora vamos utilizar o jeito Rails de fazer as coisas, faremos nosso model diferente:
Execute no terminal:
rails g model produto2 nome:string
Agora temos uma migração/migrate, pela convenção nome que ele adiciona um "s" no final do nome da tabela, além da classe Model já gerado no diretório.
Para ele criar as tabelas das migrations execute no terminal:
rake db:migrate
# ou
bundle exec rake db:migrate
Vamos testar nossa geração automática, no mesmo home_controller
faça:
@produtos = Produto2.all
O .all
tem a mesma ação do método buscar que implementamos anteriormente.
Agora os mesmos métodos utilizando o Active Record
Criar:
produto = Produto2.new
produto.nome = "Danilo"
produto.save
@produtos = Produto2.all
Atualizar:
produto = Produto2.find(1) # id a ser buscado
produto.nome = "Danilo -- 444 --"
produto.save
@produtos = Produto2.all
Exluir:
Produto2.find(1).destroy # id a ser buscado
# ou
Produto2.destroy(1) # id a ser buscado
@produtos = Produto2.all
Podemos criar uma coluna descrição no nosso banco, para testar como funciona, e em todos métodos e lugares onde utilizávamos o nome agora deve incluir o dado de descrição.
Vamos criar mais uma migration para ver como fica mais fácil:
rails g migration add_descricao_produto2
O rails retorna o nome da migration gerada, abra ela e adicione no método change
:
add_column :produto2s, :descricao, :text
Não esqueça de rodar as migrations:
rake db:migrate
# ou
bundle exec rake db:migrate
Agora temos nosso banco de dados atualizado, inclusive o arquivo schema.rb
que o rails mantém com a estrutura do banco de dados.
Caso tenha algum problema com a migration você pode voltar atrás com o rollback
:
rake db:rollback
# ou
bundle exec rake db:rollback
Precisamos fazer a view exibir os dados agora, em app/views/home/index.html.rb
faça:
<% produtos.each do |produto| %>
-
ID: <% produto.id %>
NOME: <% produto.nome %>
DESCRICAO: <% produto.descricao %>
<% end %>
E assim que funciona as migration, cada campo adicionado é automaticamente mapeado para o ActiveRecord, tendo todas opções disponíveis.
Leia o guia oficial: Active Record Migrations
Nossa aula fica por aqui, até a pŕoxima!
Arquiteto de software, analista, programador, professor. Danilo criou o projeto torne-se um programador, para passar o seu conhecimento para a nova geração. Com o intuito de ser um bom pai, Danilo trabalha muito motivado para garantir o futuro de sua filha.