"O Cliente tem sempre razão"
Nesse capítulo, você verá como trabalhar com AJAX de maneira não obstrusiva no Rails.
Se observarmos a listagem de comentários perceberemos que a experiência do usuário não é agradável, após remover um comentário o usuário é redirecionado para a listagem de comentários. Podemos utilizar AJAX para uma experiência mais marcante no uso do site pelos usuários.
Ao abrirmos o nosso partial app/views/comentarios/_comentario.html.erbveremos que há uma chamada ao helper link_to, que é responsável por criar o link (remover). Esse helper, já nos disponibiliza uma opção para realização de uma requisição AJAX. Para obter esse comportamento, devemos utilizar a opçãoremote: true, da seguinte forma:
<!-- /app/views/comentarios/_comentario.html.erb --> <p> <%= comentario.conteudo %> - <%= link_to '(remover)', comentario, method: 'delete', remote: true %> </p>
123456
Após realizar essa alteração, poderemos remover um comentário sem sair da página atual. Porém o comentario em si continuará na tela. Se recarregarmos a página o comentário não aparecerá pois ele realmente foi excluido no banco de dados.
A action ComentariosController#destroy está sendo chamada de forma assíncrona (Ajax), porém a página não foi atualizada. Por isso precisaremos utilizar um código JavaScript que irá apagar o comentário logo após a actiondestroy responder a requisição AJAX com sucesso.
É uma boa prática no desenvolvimento front-end que importemos os nossos JavaScripts sempre antes de </body>. Para fazer isso, utilizaremos uma solução muito parecida com a do CSS, utilizando yield e content_for.
Vamos começar alterando o app/views/layouts/application.html.erb para que as nossas views e partials possam inserir um conteúdo JavaScript antes do</body>
<!-- /app/views/layouts/application.html.erb --> <!-- (...) --> <script type="text/javascript"> <%= yield :js %> </script> </body> </html>
123456789
Utilizaremos um código JavaScript que irá apagar o comentário assim que a requisição AJAX for respondida como bem sucedida:
$('#remove_comentario_<%= comentario.id %>').bind('ajax:success', function(){ $('#comentario_<%= comentario.id %>').remove(); } );
Agora vamos alterar o arquivo app/views/comentarios/_comentario.html.erbpara colocar esse código JavaScript no lugar do 'yield :js'.
<p id="comentario_<%= comentario.id %>"> <%= comentario.conteudo %> <%= link_to 'remover', comentario, :method => :delete, :remote => true, :id => "remove_comentario_#{comentario.id}"%> </p> <% content_for :js do%> $('#remove_comentario_<%= comentario.id %>').bind('ajax:success', function(){ $('#comentario_<%= comentario.id %>').remove(); }); <%end%>
Perceba que também adicionamos id no parágrafo e no link, adicionamos esse atributo pois o nosso código JavaScript necessita que cada comentário tenha um parágrafo com id comentario_ID-DO-COMENTARIO e um link com idremove_comentario_ID-DO-COMENTARIO.
Dessa forma, teremos o HTML gerado será algo como:
<div id='comentarios'><h3><Comentarios></h3> <p id="comentario_1"> comentario 1 <a href="/comentarios/1" data-method="delete" data-remote="true" id="remove_comentario_1" rel="nofollow">remover</a> </p> <p id="comentario_2"> Comentario 2 <a href="/comentarios/2" data-method="delete" data-remote="true" id="remove_comentario_2" rel="nofollow">remover</a> </p> <!-- Continuação do HTML --> <script> $('#remove_comentario_1').bind('ajax:success', function(){ $('#comentario_1').remove(); }); $('#remove_comentario_2').bind('ajax:success', function(){ $('#comentario_2').remove(); }); </script>
Após implementar, nossa página deve conter o código JavaScript ao final do código fonte da página. Para verificar, abra a página de visualização de um restaurante qualquer, pressione CTRL + U e verifique no código fonte da página se o nosso novo código JavaScript foi adicionado antes da tag body.
Mesmo com o código JavaScript sendo adicionado corretamente, o parágrafo do comentário ainda não será removido. Isso ocorrerá pois nosso código JavaScript assume que a resposta da requisição AJAX será de sucesso quando na verdade, ela é uma mensagem de falha pois não preparamos nosso controller para receber uma requisição AJAX.
Portanto, para preparar nossa action destroy basta adicionarmos um novo formato ao respond_to que só responda como bem sucedida. Para isso utilizaremos o método head passando o simbolo :ok:
def destroy @comentario = Comentario.find(params[:id]) @comentario.destroy respond_to do |format| format.js { head :ok } end end
12345678
Após realizar todas essas alterações, poderemos finalmente desfrutar de um link remover que além de excluir no banco de dados, irá remover dinamicamente o parágrafo do comentário.
O Rails, antes da versão 3, tentava facilitar o desenvolvimento de código javascript com recursos como o RJS Templates, que produzia código javascript a partir de código Ruby.
Contudo, o código gerado era acoplado ao Prototype, o que dificultava o uso de outras bibliotecas populares como o jQuery. No Rails 3 optou-se por essa nova forma, não obstrutiva, de se trabalhar com javascript, permitindo que os desenvolvedores tenham controle absoluto do código criado, e podendo, inclusive, escolher a biblioteca que será usada (Prototype, jQuery, Moo-tools ou qual quer outra, desde que um driver exista para essa biblioteca).
Outra mudança interessante que mostra que o Rails é um framework em constante evolução foi a adoção do framework jQuery como padrão a partir da versão 3.1.
Vamos configurar o link remover de forma que ele realize uma requisição AJAX.
<p> <%= comentario.conteudo %> - <%= link_to '(remover)', comentario, :method => :delete, :remote => true %> </p>
12345
Apesar de ser feita uma requisição AJAX, o comentário continua aparecendo. Vamos adicionar um código JavaScript que irá apagar o parágrafo quando o link for clicado:
<p id="comentario_<%= comentario.id %>"> <%= comentario.conteudo %> - <%= link_to '(remover)', comentario, :method => :delete, :remote => true, :id => "remove_comentario_#{comentario.id}" %> </p> <% content_for :js do %> $('#remove_comentario_<%= comentario.id %>').bind('ajax:success', function(){ $('#comentario_<%=comentario.id%>').remove(); } ); <% end %>
1 2 3 4 5 6 7 8 91011121314
Como queremos que todo o JavaScript esteja posicionado antes do </body> é necessário que alteremos o layout application.html.erb.
<script> <%= yield :js %> </script>
Precisamos também preparar a action destroy do nosso controller de comentários para responder à requisições AJAX.
def destroy @comentario = Comentario.find(params[:id]) @comentario.destroy respond_to do |format| format.js { head :ok } end end
12345678
Teste em http://localhost:3000/restaurantes, selecionando um restaurante e removendo um de seus comentários.
A Alura oferece dezenas de cursos online em sua plataforma exclusiva de ensino que favorece o aprendizado com aqualidade reconhecida da Caelum. Você pode escolher um curso nas áreas de Java, Ruby, Web, Mobile, .NET e outros, ou fazer a assinatura semestral que dá acesso a todos os cursos.
Conheça os cursos online da Caelum.
Ao criar um novo comentário, fica claro que temos o mesmo problema que tinhamos no link (remover). Após criar um comentário somos redirecionados para uma outra página. Portanto resolveremos esse problema fazendo com que o formulário envie uma requisição AJAX.
Logo, precisaremos realizar uma pequena alteração no nosso partialapp/views/comentarios/_novo_comentario.html.erb para que o formulário do mesmo passe a realize requisições AJAX:
<!-- /app/views/comentarios/_novo_comentario.html.erb --> <%= form_for Comentario.new, remote: true do |f| %> <!-- (...) -->
Após utilizar a opção remote: true, conseguiremos criar um comentário, porém o mesmo não aparecerá na listagem de comentários.
$('form').bind('ajax:complete', function(){ $('#comentarios').replaceWith(result.responseText); $('textarea').val(""); });
Vamos nos aproveitar do yield :js que já foi inserido no layout, ou seja, só precisaremos adicionar a chamada ao método content_for em qualquer local do nosso partial app/views/comentarios/_novo_comentario.html.erb:
<% content_for :js do %> $('form').bind('ajax:complete', function(){ $('#comentarios').replaceWith(result.responseText); $('textarea').val(""); }); <% end %>
Após realizar essas alterações verificaremos que ao tentar criar um comentário, a listagem de comentários não é atualizada. Ao invés disso, a listagem é substituida por uma outra página. Isso ocorrerá, pois nosso código JavaScript substitui a listagem pela resposta da requisição.
Isso ocorre pois nossa action ComentariosController#create não está preparada para responder com a listagem de comentários atualizada.
Porém, nossa action ComentariosController#create precisa responder com um conteúdo para o formato js que é o utilizado para requisições AJAX. Para fazer isso, iremos criar um arquivo de extensão js.erb. Como a action que irá responder é a create iremos criar o arquivo app/views/comentarios/create.js.erb que irá simplesmente renderizar a listagem de comentários novamente:
<%= comentarios @comentario.comentavel %>
Note que nossas views anteriores utilizavam o layout application.html.erb, porém nossa nova view irá utilizar o layout de acordo com seu próprio formato, ou seja, o arquivo app/views/layouts/application.js.erb. Como a resposta terá somente a lista e nada mais, nosso novo arquivo de layout deverá ter somente duas chamadas para yield. Uma para renderizar o conteúdo da view e a outra para renderizar o código JavaScript:
<%= yield %> <script> <%= yield :js %> </script>
def create @comentario = Comentario.new params[:comentario] respond_to do |format| if @comentario.save format.js end end end
Após realizar as alterações acima, poderemos criar comentários sem ter que esperar a página inteira ser carregada. Pois a listagem de comentários será atualizada dinamicamente.
Primeiramente iremos configurar nosso formulário para criação de comentários de forma que ele realize requisições AJAX:
<%= form_for Comentario.new, remote: true do |f| %>
<% content_for :js do %> $('form').bind('ajax:complete', function(xhr, result){ $('#comentarios').replaceWith(result.responseText); $('textarea').val(""); }); <% end %>
Para finalizar o processo temos que alterar o nosso controller de comentários para responder com a lista de comentários do nosso comentável.
if @comentario.save format.js else
<%= comentarios @comentario.comentavel %>
<%= yield %> <script> <%= yield :js %> </script>
Xo สล็อตออนไลน์ โปรสล็อต XO เกมออนไลน์ทำเงินยอดฮิตเกมสล็อต xopg.net คือเกมทำเงิน reeffutures2018 ผ่านทางออนไลน์อย่างหนึ่ง ที่เล่นง่าย และได้เงินไว แถมยังลงทุนด้วยเงินน้อย mavoixtavoie ทำเงินได้ตลอดเวลา ซึ่งหลายคนอาจได้เคยเห็นรีวิวเรื่องของ สล็อต xo สล็อตออนไลน์ ไว้มากมาย เทคนิคสล็อต ทั้งเรื่องการเล่นแล้วได้เงิน herbalpertpresents และเล่น สล็อต แล้วไม่ได้เงิน นั่นเองค่ะ ซึ่งการที่คุณจะเล่นได้เงินหรือไม่ได้เงินนั้น essentialsforasoul ส่วนหนึ่งก็เป็นในเรื่องของดวงเข้ามาเกี่ยวด้วย northbristol เพราะสล็อตเป็นเกมออนไลน์เสี่ยงโชค ทดลองเล่น xo เกมหนึ่งซึ่งจะมีสูตร หรือเทคนิคเข้ามาช่วย gclub เพื่อโกงดวงอยู่เสมอซึ่งในเว็บของเรา สมัคร xo ก็มีมาแนะนำไว้ให้เห็นกันมากมายหลายสูตร