Crie sua primeira app de votação com Sinatra

Criado por Piotr Szotkowski, @chastell Traduzido por Nathalia Pinheiro Mesquita, @nathi_pinheiro

Nós vamos criar um pequeno app de votação do zero usando um framework de desenvolvimento web para Ruby chamado Sinatra, e que é muito parecido com Ruby on Rails. Mas é só outra ferramenta para fazermos nosso trabalho e uma bem divertida também!

Imagine seu grupo de amigos tentando decidir o que pedir para sua maratona de filmes semanal. Com tantas opções de fast food para pedir, isso pode se tornar uma discussão e tanto. É nessa hora que entra o nosso app!

INSTRUTOR(A): Breve explicação sobre o que é o Sinatra.

Instalação Sinatra

Lembra como nós precisávamos instalar Ruby on Rails? Da mesma maneira precisamos instalar o Sinatra:

gem install sinatra

Crie sua primeira aplicação Sinatra

Crie o arquivo sufragista.rb com o seguinte conteúdo:

require 'sinatra'

get '/' do
'Olá, eleitor!'
end

Você pode chamar seu arquivo Ruby do que preferir. voto.rb por exemplo funcionaria bem também. Mas [Sufragista] (http://www.vocabulary.com/dictionary/suffragist) é uma referencia a um evento super importante no movimento a favor do direito das mulheres, então vamos usar este por agora!

Rode sua app

Vá para o diretório onde você colocou sua app e execute ruby sufragista.rb Agora você pode visitar <a href=”localhost:4567” target=_blank”>localhost:4567</a>. Onde você deverá ver a página “Olá, eleitor!”, o que significa que a geração do seu novo app está funcionando corretamente. Aperte Ctrl+C no terminal para parar o servidor. Se Ctrl+C não funcionar para você significa que você provavelmente está usando Windows e Ctrl+Z/ Ctrl+Pause / Ctrl+Break deve resolver esse problema.

INSTRUTOR(A): Explique o método POST e GET e como eles se comunicam com o browser.

Adicione o index view

Para manter tudo em ordem vamos criar um diretório para nossas views (e nomear como views).

Coloque esse código no arquivo index.erb dentro do diretório views:

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>Sufragista</title>
<link href='//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css' rel='stylesheet' />
</head>
<body class='container'>
<p>O que tem para jantar?</p>
<form action='cast' method='post'>
<ul class='unstyled'>
<% Opcoes.each do |id, text| %>
<li>
<label class='radio'>
<input type='radio' name='vote' value='<%= id %>' id='vote_<%= id %>' />
<%= text %>
</label>
</li>
<% end %>
</ul>
<button type='submit' class='btn btn-primary'>Votar!</button>
</form>
</body>
</html>

e dentro do sufragista.rb:

Opcoes = {
'HAM' => 'Hambúrger',
'PIZ' => 'Pizza',
'SUS' => 'Sushi',
'LAM' => 'Lámen',
}

Mude a ação get:

get '/' do
erb :index
end

Execute ruby sufragista.rb, cheque seus resultados e pare o servidor com Ctrl+C.

INSTRUTOR(A): Fale um pouco sobre HTML e erb. Explique sobre templates e sobre o que são constantes globais.

Templates

Ajuste o arquivo index.erb no diretório views e adicione a linha <h1>…</h1>:

  <body class='container'>
<h1><%= @titulo %></h1>
<p>O que tem para jantar?</p>

Mude a ação get:

get '/' do
@titulo = 'Bem vindo ao Sufragista!'
erb :index
end

INSTRUTOR(A): Explique o que são instancias de variáveis e como Sinatra faz elas visíveis nas views.

Adicione a habilidade de fazer um POST dos resultados

Coloque isto no sufragista.rb:

post '/cast' do
@titulo = 'Obrigada por votar!'
@voto = params['voto']
erb :cast
end

Crie um novo arquivo cast.erb no diretório views, e coloque lá um pouco de HTML com código Ruby junto:

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>Suffragist</title>
<link href='//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css' rel='stylesheet' />
</head>
<body class='container'>
<h1><%= @titulo %></h1>
<p>Seu voto: <%= Opcoes[@voto] %></p>
<p><a href='/results'>Veja os Resultados!</a></p>
</body>
</html>

INSTRUTOR(A): Explique como o POST funciona. Como buscar o que foi mandado no formulário? de onde veio o params?

Construa um layout comum

Crie o arquivo layout.erb no diretório views. Coloque o seguinte lá:

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>Suffragist</title>
<link href='//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css' rel='stylesheet' />
</head>
<body class='container'>
<h1><%= @titulo %></h1>
<%= yield %>
</body>
</html>

Remova a parte acima dos outros dois templates (index.erb e cast.erb que estão no diretório views).

INSTRUTOR(A): Fale sobre a estrutura de documentos HTML e sobre como a construção de código comum funciona. Explique o que yield faz.

Adicione o resultado route e o resultado view

Cole o seguinte código em sufragista.rb:

get '/results' do
@votos = { 'HAM' => 7, 'PIZ' => 5, 'SUS' => 3 }
erb :results
end

Crie um novo arquivo no diretório views, chamado results.erb.

<table class='table table-hover table-striped'>
<% Opcoes.each do |id, text| %>
<tr>
<th><%= text %></th>
<td><%= @voto[id] || 0 %>
<td><%= '#' * (@voto[id] || 0) %></td>
</tr>
<% end %>
</table>
<p><a href='/'>Vote Mais!</a></p>

Execute ruby sufragistat.rb, cheque seus resultados e pause o servidor com Ctrl+C.

INSTRUTOR(A): Explique tabelas HTML e como os valores faltando vem como zero.

Guarde os resultados usando YAML::Store

Hora de algo novo! Vamos salvar nossas escolhas.

No topo de sufragista.rb, adicione o seguinte:

require 'yaml/store'

Adicione mais código em sufragista.rb – substitua post '/cast' e get '/results' com o seguinte:

post '/cast' do
@titulo = 'Obrigada por votar!'
@votos = params['voto']
@store = YAML::Store.new 'votos.yml'
@store.transaction do
@store['votes'] ||= {}
@store['votes'][@vote] ||= 0
@store['votes'][@vote] += 1
end
erb :cast
end

get '/results' do
@titulo = 'Resultados até agora:'
@store = YAML::Store.new 'votos.yml'
@votes = @store.transaction { @store['votes'] }
erb :results
end

INSTRUTOR(A): Explique o que é YAML.

Veja como o arquivo YAML muda quando votos são salvos

Vamos abrir votos.yml. E votar. E checar novamente.

INSTRUTOR(A): Vai ter situações onde um ou mais estudantes vão esquecer de pausar o servidor antes de rodá-lo novamente. É uma boa oportunidade para procurar na Internet por uma solução. Eles não tem que saber de tudo sobre “matar” processos para achar a solução.

INSTRUTOR(A): No final explique brevemente a diferença entre Sinatra e Rails.

Brinque com o app

Tente mudar algumas coisas no app como: