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', :onClick=>"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', :onClick=>"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', :onClick=>"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
PS.: agradeço se os leitores que estão gostando do tutorial colocarem links em seus blogs para o tutorial, indicando para seus amigos.
Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!



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.
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
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