Blog do Urubatan
msgbartop
Desenvolvedor, Palestrante, Escritor, Nerd Assumido e Pai do Marcus :D
msgbarbottom

16 Jul 07 Quatro dias de Ruby On Rails – Quarto e último dia

Quatro dias de Ruby On Rails – Primeiro dia, Quatro dias de Ruby On Rails – Segundo dia,

Quatro dias de Ruby On Rails – Terceiro Dia

Vamos começar agora o quarto e último dia de nosso tutorial …

A tela de Notas

Claro que o Scaffold daentidade Notes, ja cria uma estrutura completa CRUD para as notas, mas não queremos que o usuário acesse isto diretamente.

Queremos poder linkar uma nota a uma tarefa ja existente.

E caso ja exista uma nota para esta tarefa, precisamos poder editar ou remove-la.

Primeiro, vamos dar uma olhada novamente na tela de edição de tarefas. Atualmente ela ja ajusta os botões caso exista ou não uma nota para esta tarefa.

<% @heading = "Edit To Do" %>
<%= error_messages_for 'item' %>
<%= start_form_tag :action => 'update', :id => @item %>
<table>
<%= render_partial "form" %>
<tr>
<td><b>Notes: </b></td>
<% if @item.note_id.nil? %>
<td>None</td>
<td><%= link_to_image "note", :controller => "notes", :action => "new", :id => @item.id %></td>
<% else %>
<td><%=h @item.note.more_notes %></td>
<td><%= link_to_image "edit_button", :controller => "notes", :action => "edit", :id => @item.note_id %></td>
<td><%= link_to_image "delete_button", {:controller => "notes", :action => "destroy", :id => @item.note_id }, :confirm => "Are you sure you want to delete this note?" %></td>
<% end %>
</tr>
</table>
<hr />
<%= submit_tag "Save" %>
<%= submit_tag "Cancel", {:type => 'button', :o nClick=>"parent.location='" + url_for( :action => 'list' ) + "'" } %>
<%= end_form_tag %>

A tela de edição de notas.

Editar uma nota é bastante fácil, segue o template:

<% @heading = "Edit Note" %>
<%= start_form_tag :action => 'update', :id => @note %>
<%= render_partial "form" %>
<%= submit_tag "Save" %>
<%= submit_tag "Cancel", {:type => 'button', :o nClick=>"parent.location='" + url_for( :controller => 'items', :action => 'list' ) + "'" } %>
<%= end_form_tag %>

E o Partial Correspondente:

<table>
<tr>
<td><label for="note_more_notes">More notes</label></td>
<td><%= text_area 'note', 'more_notes' %></td>
</tr>
</table>

Assim que o update ou destroy de uma nota é completado, precisamos voltar a tela de listagem de tarefas.

def update
@note = Note.find(params[:id])
if @note.update_attributes(params[:note])
flash[:notice] = 'Note was successfully updated.'
redirect_to :controller => 'items', :action => 'list'
else
render :action => 'edit'
end
end
def destroy
Note.find(params[:id]).destroy
redirect_to :controller => 'items', :action => 'list'
end

Lembrem-se que as regras de integridade referencial, ja definidas no model e estas vão garantir que caso removamos uma nota, as referencias para a mesma serão removidas automaticamente.

A tela de criação de Notas.

Criar uma nova nota é um pouco mais complicado. O que queremos fazer é:

  • Armazenar a nota na tabela notes.
  • Localizar o ID da nota recem criada.
  • Armazenar o ID da nota recem criada no campo note_id da tarefa associada.

Variáveis de sessão são uma ótima forma de armazenar valores entre telas, vamos utilizar esta abordagem para armazenar o ID da tarefa associada a nova nota.

Documentação: ActionController::Base

Primeiro, quando clicamos no link para criar uma nova nota, nos passamos o ID da tarefa associada:

app\views\items\edit.rhtml (excerpt)

<td><%= link_to_image "note", :controller => "notes", :action => "new", :id => @item.id %></td>

O método “new” no controller de notas armazena este ID na sessão:

app\controllers\notes_controller.rb (excerpt)

def new
@session[:item_id] = @params[:id]
@note = Note.new
end

O template de “New Notes” não tem nenhuma novidade:

<% @heading = "New Note" %>
<%= start_form_tag :action => 'create' %>
<%= render_partial "form" %>
<%= submit_tag "Save" %>
<%= submit_tag "Cancel", {:type => 'button', :o nClick=>"parent.location='" + url_for(:controller => 'items', :action => 'list' ) + "'" } %>
<%= end_form_tag %>

O método “create” pega o ID novamente da sessão, utiliza o mesmo para buscar a tarefa do banco e atualizar o campo “note_id” na tabela items, e novamente redireciona a tela para a listagem de tarefas.

app\controllers\notes_controller.rb (excerpt)

def create
@note = Note.new(@params[:note])
if @note.save
flash['notice'] = 'Note was successfully created.'
@item = Item.find(@session[:item_id])
@item.update_attribute(:note_id, @note.id)
redirect_to :controller => 'items', :action => 'list'
else
render_action 'new'
end
end

Algumas alterações na tela de categorias.

Não sobrou muita coisa para fazer no sistema agora, alem de pequenos ajustes nas telas criadas no primeiro dia para que tenham o mesmo esquema de navegação por botões.

app\views\categories\list.rhtml

<% @heading = "Categories" %>
<form action="/categories/new" method="post">
<table>
<tr>
<th>Category</th>
<th>Created</th>
<th>Updated</th>
</tr>
<% for category in @categories %>
<tr>
<td><%=h category["category"] %></td>
<td><%= category["created_on"].strftime("%I:%M %p %d-%b-%y") %></td>
<td><%= category["updated_on"].strftime("%I:%M %p %d-%b-%y") %></td>
<td><%= link_to_image 'edit', { :action => 'edit', :id => category.id } %></td>
<td><%= link_to_image 'delete', { :action => 'destroy', :id => category.id },:confirm => 'Are you sure you want to delete this category?' %></td>
</tr>
<% end %>
</table>
<hr />
<input type="submit" value="New Category..." />
<input type="button" value="To Dos" onClick="parent.location='<%= url_for(:controller => 'items', :action => 'list' ) %>'">
</form>

app\views\categories\new.rhtml

<% @heading = "Add new Category" %>
<%= error_messages_for 'category' %>
<%= start_form_tag :action => 'create' %>
<%= render_partial "form" %>
<hr />
<input type="submit" value="Save" />
<input type="button" value="Cancel" onClick="parent.location='<%= url_for( :action=> 'list' ) %>'">
<%= end_form_tag %>

app\views\categories\edit.rhtml

<% @heading = "Rename Category" %>
<%= error_messages_for 'category' %>
<%= start_form_tag :action => 'update', :id => @category %>
<%= render_partial "form" %>
<hr />
<input type="submit" value="Update" />
<input type="button" value="Cancel" onClick="parent.location='<%= url_for( :action=> 'list' ) %>'">
<%= end_form_tag %>

Navegação pelo sistema

O grafo final de navegação pelo sistema é mostrado na imagem a baixo. Qualquer código redundante gerado pelo scaffold pode ser removido sem problemas (por exemplo show.rhtml). Esta é a beleza do scaffold, ele não te custa nada, então pode ser simplesmente excluido quando não for necessário.

Configurando a página inicial da aplicação.

Primeiro renomeie o arquivo pub.ic/index.html para public/index.html.orig

E edite o arquivo:

config\routes.rb (excerpt)

map.connect '', :controller => 'items'

Pronto, agora a tela inicial da aplicação é a listagem de tarefas.


Então era isto, fica faltando apenas o último post com os apendices.
Se tiverem duvidas é só entrar em contato :D

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!

Tags: ,

Reader's Comments

  1. |

    Urubatam, oq vc acha do Grails, eu tava dando uma olhada e achei muito bom. Vc ta testou? Oq achou dele em relação ao Ruby on Rails?
    Abraços.

    Reply to this comment
  2. |

    ja testei sim, o grails é bem legal …
    inclusive eu iria fazer uma palestra sobre ele no justjava …
    mas ja tem alguns posts sobre ele aqui no blog, é só usar o search :D

    Reply to this comment
  3. |

    Gostei do artigo, acredito que seja bom para iniciantes, aproveitei e fiz um post no meu blog pra ele.

    http://andreyviana.com/blog/2008/05/30/quatro-dias-de-ruby-on-rails/

    Abraços

    Reply to this comment
  4. |

    Nota 10, muito bom o artigo. tenho o ‘Ruby on Rails’ instalado num OpenSuse 11 (aliás uma maneira bem simples de se começar, voce instala um pacote e sai usando) e já fiz alguns testes, mas nada tão completo como esse que voce fez. vou tentar executar.
    estou querendo criar um página com Ruby on Rails, estava estudando PHP para tentar implementá-la com ele, mas depois que ouvi falar em Ruby On Rails, rasouvi mudar de direção visto que a curva de aprendizado é bem menor. Mesmo assim sei que não é tão fácil assim. Tentei comprar o livro do ‘Fábio Akita’ mas tá esgotado em todo lugar…
    Espero contar com suas dicas enquanto não consigo comprar o livro.
    Parabens.

    Reply to this comment
  5. |

    Mês que vem o meu livro esta saindo :D

    Reply to this comment
  6. |

    Assim que o seu luvro sair me avise, me mande um e-mail. tenho muito enteresse em materiais impressos sobre rails.
    além doque, estamos carentes (no Brasil) de materiais consistentes sobre o assunto.
    Boa sorte com seu livro. Espero poder ajudar (comprando, claro :) )e contar com sua ajuda nessa caminhada.

    Reply to this comment

Leave a Comment