Curso de Ruby on Rails - Aula 02

35
Aprendendo Ruby on Rails – Aula 2 Maurício Linhares

description

Material do curso de Ruby on Rails

Transcript of Curso de Ruby on Rails - Aula 02

Page 1: Curso de Ruby on Rails - Aula 02

Aprendendo Ruby on Rails – Aula 2

Maurício Linhares

Page 2: Curso de Ruby on Rails - Aula 02

Começando a usar Git e GitHub }  Crie uma conta no GitHub J

}  Na sua máquina, crie uma chave SSH: }  ssh-keygen -t rsa -C „[email protected]“ }  Não coloque senha, deixe em branco;

}  Vá até https://github.com/account e procure por “SSH public keys”;

}  Copie o arquivo “~/.ssh/id_rsa.pub” para o campo no GitHub;

Page 3: Curso de Ruby on Rails - Aula 02

Começando a usar Git e GitHub }  Teste a conexão com “ssh [email protected]”;

}  Crie um repositório pra você com o nome “linuxfi-loja”;

}  Entre dentro da pasta do seu projeto na sua máquina e : }  git config --global user.name “Seu Nome“ }  git config --global user.email “[email protected]" }  git init .

Page 4: Curso de Ruby on Rails - Aula 02

Criando o arquivo .gitignore }  Dentro da raiz do seu projeto, crie um arquivo chamado

“.gitignore”; }  gedit .gitignore

}  O conteúdo do arquivo deve ser o seguinte: }  *.log }  *.pid }  .idea/*

Page 5: Curso de Ruby on Rails - Aula 02

Preparando para enviar os arquivos }  Adicionando arquivos ao controle de versão:

}  git add . }  “.” adiciona todos os arquivos, você também pode adicionar os

arquivos um a um;

}  Aplicando as mudanças ao repoistório: }  git commit –m “Código inicial da loja” }  “commit” aplica as mudanças e salva todas as alterações

aplicadas desde o último “commit”

Page 6: Curso de Ruby on Rails - Aula 02

Enviando as alterações para o servidor do GitHub

}  Adicionando o servidor do GitHub como servidor remoto do seu código: }  git remote add origin

[email protected]:usuario-do-github/linuxfi-loja.git

}  Enviando as alterações para o servidor remoto do GitHub }  git push origin master

}  Para baixar o projeto em outra máquina: }  git clone [email protected]:usuario-do-github/linuxfi-loja.git

Page 7: Curso de Ruby on Rails - Aula 02

Workflow do trabalho no GitHub }  Desenvolva suas alterações;

}  Adicione os arquivos para alteração }  git add .

}  Salve as alterações no repositório local: }  git commit –m “mensagem”

}  Atualize o seu repositório local com as alterações do repositório remoto: }  git pull

}  Envie suas alterações para o servidor remoto: }  git push

Page 8: Curso de Ruby on Rails - Aula 02

Adicionando as mensagens em pt-BR ao Rails

}  Configurar no “config/application.rb” para utilizar “pt-BR” como língua padrão: }  config.i18n.default_locale = :'pt-BR'

}  Baixar o arquivo de I18N de: }  http://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/

pt-BR.yml

}  Salvar o arquivo em “config/locales/pt-BR.yml”;

Page 9: Curso de Ruby on Rails - Aula 02

Preparando o carrinho de compras }  Os produtos vão ser relacionar com pedidos;

}  Os pedidos não se relacionam diretamente com produtos, mas com uma tabela itens, que vai fazer a associação entre eles e adicionar atributos ao relacionamento, como quantidade;

}  Duas novas entidades surgem, Pedido e Item;

Page 10: Curso de Ruby on Rails - Aula 02

Gerando a migração para pedidos e itens

rails generate migration criar_pedidos_e_itens

Page 11: Curso de Ruby on Rails - Aula 02

Código da migration def self.up create_table :pedidos do |t| t.string :estado, :default => 'carrinho', :null => false t.timestamps end create_table :itens do |t| t.integer :pedido_id, :null => false t.integer :produto_id, :null => false t.integer :quantidade end add_index :itens, :pedido_id end def self.down drop_table :pedidos drop_table :itens end

Page 12: Curso de Ruby on Rails - Aula 02

Criando a classe Item class Item < ActiveRecord::Base belongs_to :produto belongs_to :pedido validates_presence_of :produto_id, :pedido_id, :quantidade end

Page 13: Curso de Ruby on Rails - Aula 02

Detalhes da classe item }  Itens se associam com produtos e pedidos, a tabela

“itens” guarda chaves estrangeiras para as duas outras tabelas, então o relacionamento é um “belongs_to” para cada uma delas;

}  O plural de “item” é “itens” e não “items” como seria no inglês, então é necessário configurar o inflector do Rails para agir segundo essa regra;

Page 14: Curso de Ruby on Rails - Aula 02

config/inflections.rb ActiveSupport::Inflector.inflections do |inflect| inflect.irregular 'item', 'itens' end

Page 15: Curso de Ruby on Rails - Aula 02

Criando a classe Pedido class Pedido < ActiveRecord::Base has_many :itens has_many :produtos, :through => :items end

Page 16: Curso de Ruby on Rails - Aula 02

Detalhes da classe Pedido }  Cada pedido contém vários itens, então há um

relacionamento “has_many” para a classe “Item”;

}  Com o relacionamento entre Pedido e Item, também é necessário saber exatamente quais são os produtos relacionados ao pedido, isso é feito através do relacionamento “has_many :through” entre as duas classes;

}  O “has_many :through” simplifica o acesso a objetos que sejam internos a um relacionamento já definido da classe em questão;

Page 17: Curso de Ruby on Rails - Aula 02

Adicionando a flash aos layouts }  A flash é um espaço que existe entre as requisições para

se guardar informações;

}  Normalmente é utilizada para mostrar mensagens para o usuário;

}  Os dados colocados na requisição atual, serão apagados ao fim da próxima requisição (depois do redirect);

Page 18: Curso de Ruby on Rails - Aula 02

Mas antes disso – Twitter Bootstrap! }  Conjunto de folhas de estilo e JavaScript padrões

desenvolvidos pelo Twitter;

}  Contém vários componentes visuais comuns e que podem ser utilizados em várias aplicações;

}  Facilita a estilização das suas páginas através de um CSS limpo e bem organizado;

}  http://twitter.github.com/bootstrap/

Page 19: Curso de Ruby on Rails - Aula 02

Adicione ele como dependência no seu Gemfile

}  gem 'less-rails-bootstrap', '1.3.3’

}  Execute o bundler: }  bundle install

}  Adicione ele no seu app/assets/javascripts/application.js: }  //= require twitter/bootstrap

}  Adicione ele no seu app/assets/stylesheets/application.css: }  *= require twitter/bootstrap

Page 20: Curso de Ruby on Rails - Aula 02

Alterando o app/views/layout/application.html.erb <body> <div class="container"> <% [:success, :warning, :error, :info].each do |key| %> <% unless flash[key].blank? %> <div class="alert-message <%= key %>"> <a class="close" href="javascript:void(0)">&times;</a> <p><strong><%= flash[key] %></strong></p> </div> <% end %> <% end %> <%= yield %> </div> </body>

Page 21: Curso de Ruby on Rails - Aula 02

Chamada para fechar o alerta – app/assets/javascripts/main.js

jQuery( function () { jQuery(".alert-message").alert(); } );

Page 22: Curso de Ruby on Rails - Aula 02

Definindo método pedido_atual em ApplicationController

helper_method :pedido_atual protected def pedido_atual if @pedido_atual.nil? && !session[:pedido_id].blank? @pedido_atual =

Pedido.find_by_id( session[:pedido_id] ) end @pedido_atual ||= Pedido.new end

Page 23: Curso de Ruby on Rails - Aula 02

Adicionando itens ao pedido }  O pedido atual fica guardado na sessão do usuário, o

método que faz isso é o “pedido_atual” que vai ser definido em ApplicationController;

}  O método “pedido_atual” também precisa ficar disponível nas páginas da aplicação;

}  A chamada a “helper_method :pedido_atual” faz com que o método seja copiado para as visualizações também;

Page 24: Curso de Ruby on Rails - Aula 02

Implementando a adição de produtos em Item class Pedido < ActiveRecord::Base has_many :itens has_many :produtos, :through => :items def adicionar_produto(produto, quantidade) if item = self.itens.detect { |elemento| elemento.produto == produto } item.incrementar_quantidate(quantidade) item.save else self.itens.create(:produto => produto, :quantidade => quantidade) end end end

Page 25: Curso de Ruby on Rails - Aula 02

Implementação do incrementar_quantidade em Item class Item < ActiveRecord::Base belongs_to :produto belongs_to :pedido validates_presence_of :produto_id, :pedido_id, :quantidade validates_numericality_of :quantidade, :greater_than => 0, :allow_nil => true def incrementar_quantidade(quantidade) self.quantidade += quantidade end end

Page 26: Curso de Ruby on Rails - Aula 02

Implementação da adição de produto no carrinho no ItensController class ItensController < ApplicationController def create pedido_atual.save session[:pedido_id] = pedido_atual.id pedido_atual.adicionar_produto(Produto.find(params[:produto_id]), params[:quantidade]) respond_to do |format| format.html do flash[:success] = 'O produto foi adicionado com sucesso a o seu carrinho' redirect_to produtos_path end end end end

Page 27: Curso de Ruby on Rails - Aula 02

Adicionar rota para o ItensController

resources :itens

Page 28: Curso de Ruby on Rails - Aula 02

Montando o formulário para adição de produtos ao carrinho

<%= form_tag itens_path, :html => { :method => :post }

do %> <%= hidden_field_tag :produto_id, produto.id %> <p> <%= text_field_tag :quantidade, 1 %> <%= submit_tag 'Adicionar ao carrinho' %> </p>

<% end %>

Page 29: Curso de Ruby on Rails - Aula 02

Adicionando link para visualizar o carrinho no application.html.erb <div class="topbar-wrapper" style="z-index: 5;"> <div class="topbar"> <div class="topbar-inner"> <div class="container"> <h3> <%= link_to 'Minha Loja', root_url %> </h3> <% unless pedido_atual.itens.blank? %> <ul class="nav secondary-nav"> <li> <%= link_to 'Veja o seu carrinho', itens_path %> </li> </ul> <% end %> </div> </div> </div> </div>

Page 30: Curso de Ruby on Rails - Aula 02

Complementando a classe Item class Item < ActiveRecord::Base # outros métodos aqui def preco_unitario self.produto.preco end def nome self.produto.nome end def preco_total self.produto.preco * self.quantidade end end

Page 31: Curso de Ruby on Rails - Aula 02

Porque preco_unitario e nome implementados em Item?

}  Referência a Lei de Demeter (deusa grega da Agricultura) ou o princípio do menor conhecimento;

}  Objetos devem falar somente com suas dependências diretas (variáveis de instância ou objetos recebidos como parâmetro);

}  Fazer com que um objeto dependa somente de outros objetos que estejam no mesmo “grupo” que ele;

Page 32: Curso de Ruby on Rails - Aula 02

Complementando a classe Pedido class Pedido < ActiveRecord::Base # outros métodos def preco_total self.itens.inject( 0 ) do |acumulado, item| acumulado+ item.preco_total end end end

Page 33: Curso de Ruby on Rails - Aula 02

Cabeçalho do carrinho de compras <thead> <tr> <th>Produto</th> <th>Quantidade</th> <th>Preço Unitário</th> <th>Preço Total</th> </tr> </thead>

Page 34: Curso de Ruby on Rails - Aula 02

Tabela principal do carrinho de compras <table> <tbody> <% pedido_atual.itens.each do |item| %> <tr> <td> <%= item.nome %> </td> <td> <%= item.quantidade %> </td> <td> <%= number_to_currency item.preco_unitario %></td> <td> <%= number_to_currency item.preco_total %> </td> </tr> <% end %> </tbody> </table>

Page 35: Curso de Ruby on Rails - Aula 02

Rodapé do carrinho de compras <tfoot> <tr> <td colspan="2"></td> <td> Preço Total </td> <td> <%= number_to_currency

pedido_atual.preco_total %> </td> </tr> </tfoot>