Quatro dias de Ruby On Rails – Primeiro dia
Seguindo com a tradução do tutorial, vamos ao segundo dia.
Para prosseguir alem do ponto onde ja chegamos, precisaremos olhar com maiores detalhes o que acontece por traz dos panos, principalmente o código gerado pelo scaffold.
Com a ação “scaffold :entidade” o rails gera o código necessário dinamicamente, mas podemos também gerar o código para que possamos ler e alterar …
ruby script/generate scaffold categoryexists app/controllers/ exists app/helpers/ create app/views/categories exists app/views/layouts/ exists test/functional/ dependency model exists app/models/ exists test/unit/ exists test/fixtures/ identical app/models/category.rb identical test/unit/category_test.rb identical test/fixtures/categories.yml create app/views/categories/_form.rhtml create app/views/categories/list.rhtml create app/views/categories/show.rhtml create app/views/categories/new.rhtml create app/views/categories/edit.rhtml create app/controllers/categories_controller.rb identical test/functional/categories_controller_test.rb create app/helpers/categories_helper.rb create app/views/layouts/categories.rhtml identical public/stylesheets/scaffold.css
Este escript gerou todo o código necessário para este controller.
Preste atenção na pequena diferença de nomenclatura, nos mudamos do singular para o plural, agora para acessar o controller acessaremos o endereço: http://localhost:3000/categories, na verdade é melhor remover o controller antigo para evitar confusões.
O código gerado pelo Scaffold
O controller
Vamos dar uma olhada no código do controller, o controller é o lugar para a implementação da lógica da aplicação. Ele interage com o usuário através das views e com o banco de dados utilizando os models. Você deve conseguir ler o código do controller e entender como a aplicação funciona.
O código gerado pelo scaffold deve parecer com o seguinte:
class CategoriesController < ApplicationControllerdef index list render :action => 'list' end # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post,nly => [ :destroy, :create, :update ], :redirect_to => { :action => :list } def list @category_pages, @categories = paginate :categories, :per_page => 10 end def show @category = Category.find(params[:id]) end def new @category = Category.new end def create @category = Category.new(params[:category]) if @category.save flash[:notice] = 'Category was successfully created.' redirect_to :action => 'list' else render :action => 'new' end end def edit @category = Category.find(params[:id]) end def update @category = Category.find(params[:id]) if @category.update_attributes(params[:category]) flash[:notice] = 'Category was successfully updated.' redirect_to :action => 'show', :id => @category else render :action => 'edit' end end def destroy Category.find(params[:id]).destroy redirect_to :action => 'list' end end
Quando o usuário de uma aplicação rails, por exemplo “show”, o controller vai executar o código na seção apropriada, neste caso “def show”, e depois por padrão vai rendrizar o controller de mesmo nome, neste caso “show.rhtml”, este comportamento padrão pode ser alterado com facilidade.
Documentação: ActionController::Base
O controller utiliza metodos da classe ActiveRecord por exemplo new, save, find, find_all, update_attributes e destroy para mover os dados de e para o banco de dados, perceba que não é necessário escrever nenhum SQL, mas se você quiserver o SQL que o rails esta gerando, ele é escrito para o arquivo development.log.
Documentação: ActiveRecord::Base
Perceba também que uma ação lógica, pela perspectiva do usuário, pode requerer duas passagens pelo código do controller, por exemplo quando um usuário seleciona “Edit” o controller busca os dados do banco e renderiza o template “edit.rhtml” e quando o usuário finaliza a edição, o metodo update é chamado, que por sua vez atualiza o model e renderiza a ação show.
A View
Views são o que utilizamos para definir a interface com o usuário. O Rails pode renderizar o HTML final apresentado para o usuário utilizando 3 componentes.
| Layout | Templates | Partial |
|---|---|---|
| em app\views\layouts, padrão application.rhtml, ou <controller>.rhtml | em app\views\<controller>, padrão <action>.rhtml | em app\views\<controller>, padrão _<partial>.rhtml |
Layout
Padrões de nomenclatura do Rails: se existir no diretório app\views\layouts, um arquivo com o mesmo nome do controller.rhtml este é utilizado por padrão, a não ser que outro seja configurado manualmente.
Sempre existe um arquivo de nome application.rhtml que é utilizado caso o layout do controller não seja encontrado, e nenhum outro seja configurado manualmente.
O código gerado para o layout no arquivo categories.rhtml é parecido com o seguinte:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <title>Categories: <%= controller.action_name %></title> <%= stylesheet_link_tag 'scaffold' %> </head> <body> <p style="color: green"><%= flash[:notice] %></p><%= yield %> </body></html>
A maior parte é HTML simples, mais algumas poucas entradas de código ruby entre <% e %>, Este layout sera utilizado no processo padrão de renderização, e contem o HTML padrão para todas as páginas. O código Ruby do template sera traduzido para HTML em tempo de execução.
Template
Padrões de nomenclatura do Rails: templates ficam no diretório apps\controller\`action`.rhtml
o código para o new.rhtml gerado pelo scaffold parece com o seguinte:
<h1>New category</h1> <% form_tag :action => 'create' do %> <%= render :partial => 'form' %> <%= submit_tag "Create" %> <% end %> <%= link_to 'Back', :action => 'list' %>
Partial
Padrão de nomenclatura do Rails: o partial “foo” vai estar em app/`controller`/_foo.rhtml, preste atenção no _ inicial.
O “scaffold” utiliza o mesmo código de formulário para processar o formulário de create e edit, o código dele se parece com o seguinte:
<%= error_messages_for 'category' %> <!--[form:category]--> <p><label for="category_category">Category</label><br/> <%= text_field 'category', 'category' %></p> <p><label for="category_created_on">Created on</label><br/> <%= datetime_select 'category', 'created_on' %></p> <p><label for="category_updated_on">Updated on</label><br/> <%= datetime_select 'category', 'updated_on' %></p> <!--[eoform:category]-->
<div class="errorExplanation" id="errorExplanation"> <h2>n errors prohibited this xxx from being saved</h2> <p>There were problems with the following fields:</p> <ul> <li>field_1 error_message_1</li> <li>... ...</li> <li>field_n error_message_n</li> </ul> </div>
Nos vimos o erro em ação no primeiro di, na seção capturando erros, perceba as classes css que podem ser utilizadas para alterar o estilo.
As páginas para edição e visualização são similares a de criação, ja a página de listagem possui alguns pequenos truques.
O controler executa o seguinte código para popular a listagem:
@category_pages, @categories = paginate :category, :per_page => 10
o comando “paginate” popula uma lista ordenada com “per_page” registros por vez, e contem toda a lógica de paginação.
neste caso a coleção @catetory_pages é uma instancia da classe Paginator.
vamos ver como ficou o template para esta ação:
<h1>Listing categories</h1>
<table>
<tr>
<% for column in Category.content_columns %>
<th><%= column.human_name %></th>
<% end %>
</tr>
<% for category in @categories %>
<tr>
<% for column in Category.content_columns %>
<td><%=h category.send(column.name) %></td>
<% end %>
<td><%= link_to 'Show', :action => 'show', :id => category %></td>
<td><%= link_to 'Edit', :action => 'edit', :id => category %></td>
<td><%= link_to 'Destroy', { :action => 'destroy', :id => category }, :confirm => 'Are you sure?', :method => :post %></td>
</tr>
<% end %>
</table>
<%= link_to 'Previous page', { :page => @category_pages.current.previous } if @category_pages.current.previous %>
<%= link_to 'Next page', { :page => @category_pages.current.next } if @category_pages.current.next %>
<br />
<%= link_to 'New category', :action => 'new' %>
Melhorando um pouco o código gerado
O Controller:
def list
@category_pages, @categories = paginate :categories, :per_page => 10,
rder_by => "category"
end
Para que a lista ja venha ordenada
Bom, por enquanto é isto, no proximo “Dia” com o Rails, vamos adicionar os cadastros de notas e itens, e brincar um pouco com os helpers do Rails.
Tudo pronto? então siga para o Terceiro dia.
PS.: agradeço se os leitores que estão gostando do tutorial colocarem links em seus blogs para o tutorial, indicando para seus amigos.
If you enjoyed this post, make sure you subscribe to my RSS feed!
Urubatan, você que é o Cara em Java, me diz uma coisa, eu trabalho com JSF, tenho vários clientes que utilizam aplições que desenvolvi em Java, e vendo todo esse aue em torno de Ruby me preocupa o fato de eu ter me especiazado em Java, será que devo me preocupar em estudar logo outra linguagem ou deve continuar firme e forte no java.? grato, Anderson.
[Translate]
Aprender mais uma linguagem é sempre vantagem, mas se a tua preocupação é se alguma coisa vai ser descontinuada, não esquenta a cabeça …
Ruby, e o Rails são alternativas para desenvolver alguns tipos de aplicações …
Algumas aplicações que são escritas em Java poderiam ter sido desenvolvidas com RoR, outras seria problemático tentar escrever com RoR.
mas o Java tem vida longa ainda
o ideal é conhecer diversas opções para poder escolher qual a melhor para cada caso …
Por exemplo este blog utiliza o wordpress que é uma aplicação escrita em PHP, mas esta rodando em uma implementação de PHP em Java, em um Tomcat.
é possivel fazer a mesma coisa com o RoR …
mas como eu disse antes, cada caso é um caso …
[Translate]
sessão ou seção? Que eu saiba, rails não suporta o conceito de sessão como no HttpSession do Java…
[Translate]
sorry, erro meu, neste caso é seção (de parte do código)
mas Bla, o Rails suporta sim um conceito parecido com HttpSession do java, e é bem fácil de utilizar …
Vamos ver isto no “Dia 4″, mas para colocar qualquer coisa no sessão do usuário no Rails basta executar um código parecido com:
[Translate]
Olá amigo. Estou gostando bastante deste tutorial. Gostaria de saber se o material referente ao terceiro dia já se encontra disponível. Abraço!
[Translate]
ta quase pronto, só não esta pronto ainda por que depois que formatei o meu note, eu fiquei com preguiça de escrever
Vou ver se consigo terminar hoje ou amanha
[Translate]
Olá Urubatan,
vejo que você possui um bom conhecimento em RoR.
Cara estou com um problema e ainda não encontrei uma solução boa,
encontrei parte dela. Bom o problema é o seguinte tem um link remote
que renderiza numa div um partial e dentro desse partial preciso
fazer uma paginação, porém não tem como eu passar por um controller
pois estou usando um esquema generalizado de chamadas remotas.
Gostaria de saber se tem como fazer o paginate no partial(.rhtml),
é que estou tentando fazer aqui e não da certo.
Se você tiver alguma solução para ajudar ficarei grato.
att
[Translate]