Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

js .erbが読み込まれないことの解決策

解決したいこと

Ruby on Rails で非同期でのいいねを実装するために
js.erbファイルを作成したのですが、うまく読み込まれずに困っています。

記事を色々と参考にしながら解決策を試しているのですが、
全く進展できずここだけで2日立ってしまいました。

参考記事
https://qiita.com/tatsuhiko-nakayama/items/b2f0c77e794ca8c9bd74

このまま解決できないまま同期通信でいいね機能を組み込むことはできるのですが、
できるなら非同期で組み込みたいと思っています。
ご助力お願いします

発生している問題・エラー


Started DELETE "/like/31" for ::1 at 2021-12-24 15:12:10 +0900
Processing by LikesController#destroy as JS
  Parameters: {"post_id"=>"31"}
  Post Load (0.4ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 31 LIMIT 1
  ↳ app/controllers/likes_controller.rb:20:in `set_controller'
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
  ↳ app/controllers/likes_controller.rb:13:in `destroy'
  Like Load (0.4ms)  SELECT `likes`.* FROM `likes` WHERE `likes`.`user_id` = 1 AND `likes`.`post_id` = 31 LIMIT 1
  ↳ app/controllers/likes_controller.rb:13:in `destroy'
   (0.2ms)  BEGIN
  ↳ app/controllers/likes_controller.rb:14:in `destroy'
  Like Destroy (0.3ms)  DELETE FROM `likes` WHERE `likes`.`id` = 37
  ↳ app/controllers/likes_controller.rb:14:in `destroy'
   (1.5ms)  COMMIT
  ↳ app/controllers/likes_controller.rb:14:in `destroy'
   (0.4ms)  SELECT COUNT(*) FROM `likes` WHERE `likes`.`post_id` = 31
  ↳ app/controllers/likes_controller.rb:15:in `destroy'
  Rendering likes/destroy.js.erb
  Rendered likes/destroy.js.erb (Duration: 2.5ms | Allocations: 1166)
Completed 500 Internal Server Error in 17ms (ActiveRecord: 3.6ms | Allocations: 6747)



ActionView::Template::Error (Missing partial likes/_like with {:locale=>[:ja], :formats=>[:js, :html, :text, :css, :ics, :csv, :vcf, :vtt, :png, :jpeg, :gif, :bmp, :tiff, :svg, :mpeg, :mp3, :ogg, :m4a, :webm, :mp4, :otf, :ttf, :woff, :woff2, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip, :gzip], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
  * "/Users/tatsuya/projects/wing/app/views"
  * "/Users/tatsuya/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/devise-4.8.0/app/views"
  * "/Users/tatsuya/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/actiontext-6.0.4.1/app/views"
  * "/Users/tatsuya/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/actionmailbox-6.0.4.1/app/views"
):
    1: console.log($.fn.jquery)
    2: $(".buttons_<%= @post.id %>").html("<%= j(render partial: 'likes/like') %>");

app/views/likes/destroy.js.erb:2

コンソール画像
https://gyazo.com/caeadae415ba766e4fdf56506c3763a2

該当するビューファイル

posts/index.html.erb
    <div class="tweet_content_area">
        <% @posts.each do |tweet| %>
          <div class="tweet_content">
              <div class="tweet_user">
                <div>
                <% if tweet.user.profile.image.attached? %>
                  <%= image_tag tweet.user.profile.image ,class: "tweet_user_image" %>
                <% else %>
                  <%= image_tag "profile_sample_images.png" ,class: "tweet_user_image" %>
                <% end %>
                  <%= link_to tweet.user.profile.nickname, profile_path(tweet.user_id) ,class: "tweet_user_name" %> &emsp;&emsp;
                  <%= tweet.created_at.to_s(:datetime_jp) %> 
              </div>
              <div>
                <% if user_signed_in? && current_user.id == tweet.user_id %>
                  <%= link_to "削除する", post_path(tweet.id) ,method: :delete ,class: "tweet_btn"%>
                <% elsif user_signed_in? %>
                  <%= link_to "コメントを見る", post_path(tweet.id) , class: "tweet_btn"%>
                <% else %>

                <% end%>
              </div>
              <p class="comment_count">コメント数: <%= tweet.comments.length%>件</p>
          </div>

              <div class="tweet"> 
                <div class="tweet_tweet">
                  <%= safe_join(tweet.tweet.split("\n"),tag(:br)) %>
                </div>
                <div class="tweet_image_area">
                  <%= image_tag tweet.image ,class: "tweet_image" if tweet.image.attached? %>
                </div>
              </div>

    #  ここからいいねボタンの記述です

            <div class= "buttons_<%= tweet.id %>">
              <% if current_user.likes.find_by(post_id: tweet.id) %>
                    <%= link_to unlike_path(tweet.id), method: :delete, remote: true do %>
                    <div class= "buttons_"><%= @like_count %></div>
                <% end %>
              <% else %>
                    <%= link_to like_path(tweet.id), method: :post, remote: true do %>
                    <div class= "buttons_">♡️<%= @like_count %></div>
                <% end %>
              <% end %>
          </div>
          </div>
        <% end %>
    </div>
  </div>

呼び出したいjs.erbコード

create.js.erb
console.log($.fn.jquery)
$(".buttons_<%= @post.id %>").html("<%= j(render partial: 'likes/like') %>");
destroy.js.erb
console.log($.fn.jquery)
$(".buttons_<%= @post.id %>").html("<%= j(render partial: 'likes/like') %>");

appllcation.jsのコード

appllcation.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery')
document.addEventListener("turbolinks:load", () => {
  console.log($.fn.jquery)
})

各コントローラー

posts_controller.rb
  def index
    @post = Post.new
    @posts = Post.includes(:user).order("created_at DESC")
    @like_count = Like.where(post_id: params[:id]).count
  end
likes_controller.rb
  before_action :set_controller

  def create
    @like = current_user.likes.new(post_id: params[:post_id])
    @like.save
    @like_count = Like.where(post_id: params[:post_id]).count
    # redirect_to root_path
  end

  def destroy
    @like = Like.find_by(user_id: current_user.id, post_id: params[:post_id])
    @like.destroy
    @like_count = Like.where(post_id: params[:post_id]).count
    # redirect_to root_path
  end

  def set_controller
    @post = Post.find(params[:post_id])
  end

自分で試したこと

最初はjquely-railsのgemをbundle installしていたのですが、
railsのバージョンが6だったので間違っていることに気が付き、
yarnからインストールしました。
その後environment.jsの記述を直して、Ajax通信をできるように直しました。

environment.js
const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)

module.exports = environment

ですが、肝心のいいねボタンをクリックすると非同期通信が行われず、ページをリロードすると
いいねボタンの色が変わります。
ということはリクエストは正常に送られていると思うのですが、上記のエラーが発生します。
テンプレート名を変更しても何も変わらず、どうしたらいいかわかりません。

無知を承知で何かご助言、解決策をお願いします。

また、いいねボタン横のカウンターも動かず、定義が間違っているのでしょうか?

0

1Answer

ぱっと見での話なので指摘間違ってたらすいません。
非同期で通信したいなら、バックエンドはAPI形式にする必要あるのではないでしょうか。
普通にhtmlとか返すバックエンドなら再描画しないと反映されないとかじゃないですかね?

「フロントからajaxで送って、バックエンドでjson返す、jsで受け取ってdom操作」
「フロントからaxiosとかで送って、バックエンドでjson返す、jsで受け取ってreactとかでバインディング」
とか
https://mintaku-blog.net/rails-asynchronous/

0Like

Comments

  1. 返信が遅れて申し訳ありません!
    自分の勉強不足を痛感しました...
    再度勉強して実装できるように努力します。

    回答いただきましてありがとうございます!

Your answer might help someone💌