2. 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 „seu@email.com“
} 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;
3. Começando a usar Git e GitHub
} Teste a conexão com “ssh git@github.com”;
} 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 “seu@email.com"
} git init .
4. 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/*
5. 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”
6. 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
git@github.com: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 git@github.com:usuario-do-github/linuxfi-loja.git
7. 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
8. 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”;
9. 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;
10. Gerando a migração para pedidos e itens
rails generate migration criar_pedidos_e_itens
11. 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
12. Criando a classe Item
class Item < ActiveRecord::Base
belongs_to :produto
belongs_to :pedido
validates_presence_of :produto_id, :pedido_id, :quantidade
end
13. 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;
15. Criando a classe Pedido
class Pedido < ActiveRecord::Base
has_many :itens
has_many :produtos, :through => :items
end
16. 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;
17. 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);
18. 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/
19. 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
21. Chamada para fechar o alerta – app/assets/
javascripts/main.js
jQuery( function () {
jQuery(".alert-message").alert();
} );
22. 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
23. 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;
24. 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
25. 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
26. 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
28. 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 %>
29. 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>
30. 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
31. 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;
32. 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
33. 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>
34. 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>
35. 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>