Falta ainda escrever a funcionalidade de adicionar comentários aos nossos restaurantes e qualificações.
Podemos, aqui, utilizar AJAX para uma experiência mais marcante no uso do site pelos usuários.
Nosso primeiro passo será possibilitar a inclusão da lista de comentários nas páginas de qualquer modelo que seja comentável. Para não repetir este código em todas as páginas que aceitem comentários, podemos isolá-lo em um helper:
def comentarios(comentavel)
comentarios = "<div id=’comentarios’>"
comentarios << "<h3>Comentarios</h3>"
comentavel.comentarios.each do |comentario|
comentarios << render(:partial => "comentarios/comentario", :locals => { :comentario => comentario }) end
comentarios << "</div>"
raw comentarios end
Podemos simplificar o código acima, utilizando a opção:collection. Dessa maneira, o partial é renderizado uma vez para cada elemento que eu tenha no meu array:
def comentarios(comentavel)
comentarios = "<div id=’comentarios’>"
comentarios << "<h3>Comentarios</h3>"
comentarios << render(:partial => "comentarios/comentario",
:collection => comentavel.comentarios) unless comentavel.comentarios.empty?
comentarios << "</div>"
raw comentarios end
Capítulo 12 - Ajax com Rails - Criando as chamadas AJAX - Página 137
Agora, vamos criar o partial responsável pela renderização de cada um dos comentários. Repare que usamos o método link_to passando o parâmetro :remote => true, que faz uma chamada a uma url utilizando para isso uma requisição assíncrona (AJAX):
<!-- /app/views/comentarios/_comentario.html.erb -->
Além disso, precisamos invocar nosso helper em app/views/restaurantes/show.html.erb e app/views/qualificacoes/show.html.erb:
<%= comentarios @qualificacao %>
Tente clicar no link e verá que nada acontece, porém ao recarregar a página, o comentário foi removido!
A açãoComentariosController#destroyestá sendo chamada de forma assíncrona (Ajax), porém a página não foi atualizada. Por isso precisamos tratar a responsta do servidor para remover o item da página.
Para isso, primeiramente vamos alterar oapp/views/layouts/application.html.erbpara nos possibilitar escre-vermos javascript no mesmo arquivo que exibe os comentários.
<!-- /app/views/layouts/application.html.erb -->
Usando oyield passando um símbolo como parâmentro podemos usar o métodocontent_for nas nossas views e fazer um tipo de include inteligente nos nossos arquivos.
Agora vamos alterar novamente o arquivo app/views/comentarios/_comentario.html.erb para colocar o ja-vascript que será renderizado no lugar do ‘yield :js’.
<p id="comentario_<%= comentario.id %>">
<%= comentario.conteudo()%>
Capítulo 12 - Ajax com Rails - Criando as chamadas AJAX - Página 138
Material do Treinamento Desenvolvimento Ágil para Web 2.0 com Ruby on Rails
<%= link_to ’remover’, comentario,
:method => :delete, :remote => true,
:id => "remove_comentario_#{comentario.id}"%>
Dessa forma, teremos um html gerado parecido com esse:
<div id=’comentarios’><h3><Comentarios></h3>
<!-- Continuação do HTML -->
<script type="text/javascript">
Capítulo 12 - Ajax com Rails - Criando as chamadas AJAX - Página 139
Basta fazermos com que nossa actiondestroynão renderize nada , adicionando mais um formato ao bloco respond_to:
def destroy
@comentario = Comentario.find(params[:id])
@comentario.destroy
respond_to do |format|
format.xml { head :ok } format.js { head :ok } end
end end
12.4 - Exercícios
1) Vamos instalar o JQuery na nossa aplicação
a) Apague todos os arquivos que estão no diretório public/javascript
b) Copie os arquivos que estão no diretório caelum/71/javascript que está no seu Desktop para o diretório public/javascript da sua aplicação.
Capítulo 12 - Ajax com Rails - Exercícios - Página 140
Material do Treinamento Desenvolvimento Ágil para Web 2.0 com Ruby on Rails
c) Abra o arquivo ** app/views/layout/application.html.erb d) Altere a linha
<%= javascript_include_tag :default %>
para
<%= javascript_include_tag ’jquery’, ’rails’ %>
e) ainda nesse arquivo adicione o yield para javascripts no final dobody
<script type="text/javascript">
<%=yield :js%>
</script>
Capítulo 12 - Ajax com Rails - Exercícios - Página 141
2) Vamos adicionar os comentários nas views.
a) Abra o arquivoapp/helpers/application_helper.rb b) Insira as seguintes linhas:
def comentarios(comentavel)
comentarios = "<div id=’comentarios’>"
comentarios << "<h3>Comentarios</h3>"
comentarios << render(:partial => "comentarios/comentario", :collection => comentavel.comentarios) comentarios << "</div>"
raw comentarios end
Capítulo 12 - Ajax com Rails - Exercícios - Página 142
Material do Treinamento Desenvolvimento Ágil para Web 2.0 com Ruby on Rails
c) Crie o arquivoapp/views/comentarios/_comentario.html.erbcom o seguinte conteúdo:
<p id="comentario_<%= comentario.id %>">
<%= comentario.conteudo %>
-<%= link_to ’(remover)’, :url => comentario, :method => :delete, :remote => true,
:id => "remove_comentario_#{comentario.id}" %>
</p>
<%=content_for :js do%>
$(’#remove_comentario_<%=comentario.id%>’).bind(
’ajax:success’,
function(xhr, result){
$(’#comentario_<%=comentario.id%>’).remove();
} );
<%end%>
Capítulo 12 - Ajax com Rails - Exercícios - Página 143
d) Altere as seguintes linhas da actiondestroydo controllercomentarios_controller.rb def destroy
@comentario = Comentario.find(params[:id])
@comentario.destroy respond_to do |format|
format.xml { head :ok } format.js { head :ok } end
end
e) Adicione a seguinte linha emapp/views/restaurantes/show.html.erb
<% unless @restaurante.comentarios.empty?%>
Capítulo 12 - Ajax com Rails - Exercícios - Página 144
Material do Treinamento Desenvolvimento Ágil para Web 2.0 com Ruby on Rails
<%= comentarios @restaurante %>
<% end %>
f) Adicione a seguinte linha emapp/views/qualificacoes/show.html.erb
<% unless @qualificacao.comentarios.empty?%>
<%= comentarios @qualificacao %>
<% end %>
Capítulo 12 - Ajax com Rails - Exercícios - Página 145
g) Teste em http://localhost:3000/restaurantes, escolhendo um restaurante no qual você já tenha inserido comentários.