質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

0回答

758閲覧

ajax(非同期通信)の実装において、「いいね」ボタンを押してもjavascriptが反映されない

skem

総合スコア1

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/10/16 03:08

編集2020/10/21 02:53

TwitterのようなSNSアプリを作成しています。railsでjavascriptを書いて「いいね」を非同期通信にしたいのですが、下記のコードを書いて、画面上で「いいね」ボタンを押しても「いいね」が反映されません。ただ、HTML/CSSは記述できているため、リロードすると反映されます。

viewファイル
renderから部分テンプレートを使っています。

.like %div{:id => "likes_buttons_#{m.id}"} = render partial: 'likes/like', locals: { m: m}

likes/_like.html.haml

- if current_user.already_like_this?(m) - like = current_user.likes.find_by(message_id: m.id) = link_to user_message_like_path(current_user.id,m.id,like.id), method: :delete, remote: true do %i.fas.fa-heart.unlike-btn - else = link_to user_message_likes_path(current_user.id,m.id), method: :post, remote: true do %i.far.fa-heart.like-btn

【likesコントローラー】

class LikesController < ApplicationController def create unless current_user.already_like_this?(clicked_message) @like = current_user.like_this(clicked_message) flash[:success] = '投稿に「いいね!」しました。' if @like.save respond_to :js end end end def destroy @like = current_user.likes.find_by(message_id: params[:message_id]).destroy flash[:danger] = '「いいね!」を解除しました。' if @like.destroy respond_to :js end end private def clicked_message Message.find(params[:message_id]) end end

【create.js.erb】

$('#likes_buttons_<%= @like.id %>'). html("<%= j(render partial: 'likes/like', locals: {m: @like}) %>");

【ターミナル】
「いいね」を押した時に、ターミナル上では下記のように出ているので、JSファイルが送られていると思うのですが。。

Started POST "/users/1/messages/140/likes" for ::1 at 2020-10-16 11:47:34 +0900 Processing by LikesController#create as JS Parameters: {"user_id"=>"1", "message_id"=>"140"} User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1 Message Load (0.2ms) SELECT `messages`.* FROM `messages` WHERE `messages`.`id` = 140 LIMIT 1 Message Exists (0.2ms) SELECT 1 AS one FROM `messages` INNER JOIN `likes` ON `messages`.`id` = `likes`.`message_id` WHERE `likes`.`user_id` = 1 AND `messages`.`id` = 140 LIMIT 1 CACHE (0.0ms) SELECT `messages`.* FROM `messages` WHERE `messages`.`id` = 140 LIMIT 1 [["id", 140], ["LIMIT", 1]] Like Load (0.2ms) SELECT `likes`.* FROM `likes` WHERE `likes`.`user_id` = 1 AND `likes`.`message_id` = 140 LIMIT 1 (0.2ms) BEGIN Message Load (0.2ms) SELECT `messages`.* FROM `messages` WHERE `messages`.`id` = 140 LIMIT 1 Like Exists (0.2ms) SELECT 1 AS one FROM `likes` WHERE `likes`.`message_id` = 140 AND `likes`.`user_id` = 1 LIMIT 1 SQL (1.7ms) INSERT INTO `likes` (`message_id`, `user_id`, `created_at`, `updated_at`) VALUES (140, 1, '2020-10-16 02:47:34', '2020-10-16 02:47:34') (0.4ms) COMMIT (0.1ms) BEGIN Like Exists (1.0ms) SELECT 1 AS one FROM `likes` WHERE `likes`.`message_id` = 140 AND (`likes`.`id` != 378) AND `likes`.`user_id` = 1 LIMIT 1 (0.1ms) COMMIT Rendering likes/create.js.erb Rendered likes/_like.html.haml (2.2ms) Rendered likes/create.js.erb (4.9ms) Completed 200 OK in 39ms (Views: 18.0ms | ActiveRecord: 4.9ms)

ご助言頂ければ幸いです。

【10/17 実施事項追記】

他の記事に「idを統一する」と書かれていたので確認した所、
viewファイルが下記"likes_buttons_#{m.id}"で、

.like %div{:id => "likes_buttons_#{m.id}"} = render partial: 'likes/like', locals: { m: m}

create.js.erbが下記'#likes_buttons_<%= @like.id %>'のようになっていたので、

$('#likes_buttons_<%= @like.id %>'). html("<%= j(render partial: 'likes/like', locals: {m: @like}) %>");

create.js.erbのidを以下'#likes_buttons_<%= m.id %>'のように書き換えました。

$('#likes_buttons_<%= m.id %>'). html("<%= j(render partial: 'likes/like', locals: {m: @like}) %>");

改めて「いいね」ボタンを押すと、今度はconsoleで以下のように出て、
イメージ説明

ターミナルでは下記のように出ました。

ActionView::Template::Error (undefined local variable or method `m' for #<#<Class:0x00007fb36301dab0>:0x00007fb3742adfd0>): 1: $('#likes_buttons_<%= m.id %>'). 2: html("<%= j(render partial: 'likes/like', locals: {m: @like}) %>");

なので今度は、
viewファイルのidを、"likes_buttons_#{@message.id}"
create.js.erbのidを、'#likes_buttons_<%= @message.id %>'
と書き換えました。

再々度「いいね」ボタンでチャレンジすると、ターミナルのエラーが下記に変わりました(consoleは上記同様のエラー)。

ActionView::Template::Error (undefined method `id' for nil:NilClass): 1: $('#likes_buttons_<%= @message.id %>'). 2: html("<%= j(render partial: 'likes/like', locals: {m: @like}) %>");

create.js.erbのlocals: {m: @like}が間違っている気もするので、調べてみたいと思います。

ご指摘等ございましたら、よろしくお願い致します。
【10/21 実施事項追記】

idを変えるとエラーが出るので、当初のコード(【10/17 実施事項追記】より以前)に戻しました。

この状態で「いいね」(または、いいね解除)を押すと、リアルタイムでは反映されないのですが、

  • google chromeのconsole上でエラーは出ていない
  • リロードしたら正しく反映される
  • ターミナルを確認するとjsファイルが送られている履歴

上記3点からJS側で何らかの通信設定が原因かと思います。

「いいね」以外にメッセージ投稿機能を設置している(こちらは正常にajaxが機能する)のですが、
下記ファイルとの兼ね合いで何か原因があるのか?

app/assets/javascripts/comment.js

$(function(){ function buildHTML(j){ if ( j.content ) { var html = `<div class="message"> <div class="takerface"> <img src=${"https://imgc.eximg.jp/i=https%253A%252F%252Fs.eximg.jp%252Fexnews%252Ffeed%252FRen_ai%252FRen_ai_188420_6aed_1.jpg,zoom=600,quality=70,type=jpg"} > </div> <div class="contents"> <div class="takername"> ${j.user_name + " さんへ"} </div> <div class="letter"> <p class="lower-message__content"> ${j.content} </p> </div> <div class="credo"> #仕事好き #親身心 #人生を変える </div> <div class="like"> <a href="users/${j.user_id}/messages/${j.message_id}/likes" data-method="post"> <i class="far fa-heart like-btn"> </i> </a> ${j.like_count} </div> </div> <div class="message__date"> ${j.created_at} </div> <div class="more"> <ul class="more_list"> <li> <a href="users/${j.user_id}/messages/${j.message_id}/edit">編集</a> </li> <li> <a href="users/${j.user_id}/messages/${j.message_id}" data-method="delete">削除</a> </li> </ul> </div> </div>` return html; } } $('#new_message').on('submit', function(e){ e.preventDefault(); var formData = new FormData(this); var url = $(this).attr('action'); $.ajax({ url: url, //同期通信でいう『パス』 type: 'POST', //同期通信でいう『HTTPメソッド』 data: formData, dataType: 'json', processData: false, contentType: false }) .done(function(data){ var html = buildHTML(data); $('.messages').append(html); $('form')[0].reset(); $('.messages').animate({ scrollTop: $('.messages')[0].scrollHeight}); $(".form__submit").removeAttr("disabled"); }) .fail(function() { alert("メッセージ送信に失敗しました"); }); }) });

着目すべき視点等ご共有頂ければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatsu

2020/10/16 15:33

consoleエラーとかって出ていたりしますでしょうか? また2個目のコードブロックがlikes/like.html.hamlでしょうか?
skem

2020/10/17 02:34 編集

・「いいね(orいいね解除)」を押しても、Googleの検証では、consoleエラーは出ていない状態です。 →idを統一した所、上記のようにconsoleエラーが出るようになりました。 ・はい、2個目のコードブロックはlikes/like.html.hamlです。質問内容に追記しておきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問