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

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

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

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

Q&A

解決済

1回答

836閲覧

いいね(Like)機能を正しく設定したい

you_your

総合スコア2

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

0グッド

0クリップ

投稿2023/09/04 13:11

編集2023/09/05 04:39

いいね(Like)ぼたんをクリックすると表示が変わるように実装したい

  • 投稿画面でLikeボタンをクリックするとLikedとなりもう一度クリックするとLikedに表示が変更するように実装したい機能を動作するようにする

前提

いいねボタンを実装中、ブラウザ上で一度クリックするとLike→Likedに変わり
もう一度クリックするとLiked→Likeに変更させたいのですが表示が変わらず特にエラーも出ません。
イベント発火もしていないようでして、binding.pryを実行しましたがターミナルでも何も表示されませんでした。
どのファイルの記述がおかしいのか回答いただけると嬉しいです。
投稿に慣れていないなので投稿内容も違和感があると思いますがよろしくお願いします。

該当のソースコード

_like.html.erb

1<% if user_signed_in? && tweet.liked_by?(current_user)%> 2 <%=link_to "Liked", tweet_likes_path(tweet.id), data: { turbo_method: :delete }, class: "tweet_likes" , remote: true %> 3<% else %> 4 <%=link_to "Like", tweet_likes_path(tweet.id), data: { turbo_method: :post }, class: "tweet_likes" , remote: true %> 5<% end %>

like.rb

1class Like < ApplicationRecord 2 belongs_to :user 3 belongs_to :tweet 4end

like.controller.rb

1class LikesController < ApplicationController 2 before_action :set_tweet 3 before_action :authenticate_user! 4 5 def create 6 like = current_user.likes.build(tweet_id: params[:tweet_id]) 7 like.save 8 respond_to do |format| 9 format.js 10 end 11 end 12 13 def destroy 14 like = Like.find_by(tweet_id: params[:tweet_id], user_id: current_user.id) 15 like.destroy 16 respond_to do |format| 17 format.js 18 end 19 end 20 21 private 22 23 def set_tweet 24 @tweet = Tweet.find(params[:tweet_id]) 25 end 26 27end

routes.rb

1Rails.application.routes.draw do 2 devise_for :users 3 root to: 'tweets#index' 4 resources :tweets do 5 resources :comments, only: :create 6 resources :likes, only: [:create, :destroy] 7 collection do 8 get 'search' 9 end 10 end 11 resources :users, only: :show 12end

tweet.rb

1class Tweet < ApplicationRecord 2 validates :text, presence: true 3 belongs_to :user 4 has_many :comments 5 has_one_attached :image 6 has_many :likes, dependent: :destroy 7 8 def liked_by?(user) 9 likes.where(user_id: user.id).exists? 10 end 11 12 def self.search(search) 13 if search != "" 14 Tweet.where('text LIKE(?)', "%#{search}%") 15 else 16 Tweet.all 17 end 18 end 19end

tweet.html.erb

1 2<div id="like-btn<%= tweet.id %>"> 3 <%= render partial: "likes/like", locals: { tweet: tweet } %> 4</div> 5<div class="content_post" style="background-image: url(<%= tweet.image %>);"> 6 <div class="tweet__image"> 7 <%= image_tag tweet.image %> 8 </div> 9 <div class="more"> 10 <span><%= image_tag 'arrow_top.png' %></span> 11 <ul class="more_list"> 12 <li> 13 <%= link_to 'Detail', tweet_path(tweet.id)%> 14 </li> 15 <% if user_signed_in? && current_user.id == tweet.user_id %> 16 <li> 17 <%= link_to 'Edit', edit_tweet_path(tweet.id)%> 18 </li> 19 <li> 20 <%= link_to 'Delete', tweet_path(tweet.id), data: { turbo_method: :delete } %> 21 </li> 22 <% end %> 23 </ul> 24 </div> 25 <p><%= tweet.text %></p> 26 <span class="name"> 27 </span> 28</div>

試したこと

ネストの記述がおかしいのではと記述を変更したりしましたが特に挙動に変化はありませんでした。
リンク内容

追加

likescontroller

1class LikesController < ApplicationController 2 before_action :set_tweet 3 before_action :authenticate_user! 4 5 def create 6 binding.pry 7 like = current_user.likes.build(tweet_id: params[:tweet_id]) 8 like.save 9 respond_to do |format| 10 format.js 11 end 12 end 13 14 def destroy 15 16 like = Like.find_by(tweet_id: params[:tweet_id], user_id: current_user.id) 17 like.destroy 18 respond_to do |format| 19 format.js 20 end 21 end 22 23 private 24 25 def set_tweet 26 @tweet = Tweet.find(params[:tweet_id]) 27 end 28 29end

を実行し、ターミナルではこちらの表示になりました。
bindin.pryの使い方も間違いでしょうか?

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

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

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

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

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

winterboum

2023/09/04 22:40

「いいねボタンを実装中、ブラウザ上で一度クリックするとLike→Likedに変わり もう一度クリックするとLiked→Likeに変更させたいのですが表示が変わらず特にエラーも出ません。」 ですと、どこまでできてどこからできないのかが判りにくいです。codeから判断して 「ブラウザ上で一度クリックするとLike→Likedに変わり」もできていない、と判断して合ってますか? 「イベント発火もしていないようでして、binding.pryを実行しましたがターミナルでも何も表示されません」 とのことですが、どこにbinding.pryを入れましたか? 質問のcode書き直して示して下さい。 「ブラウザ上で一度クリックするとLike→Likedに変わり」のときに、リロードするとLikedになってませんか?
you_your

2023/09/05 02:22

*「ブラウザ上で一度クリックするとLike→Likedに変わり」もできていない、と判断して合ってますか? -クリックするとLikedには変わっています。 *「ブラウザ上で一度クリックするとLike→Likedに変わり」のときに、リロードするとLikedになってませんか? -リロードせずにLikedに変化します。 コードを書き換えるのは時間いただきます。 返答になっていない場合はすみません。
winterboum

2023/09/05 04:13

liked にするのは行けてるのですね、 liked を like にするほうがだめ。 でしたら、 それを行ったあとで リロードしたら表示どうなってます?
you_your

2023/09/05 04:25

返信ありがとうございます。 今確認してみます。 少々お待ちください。
you_your

2023/09/05 04:26

実行しましたがLikedから何も変化ありませんでした。
you_your

2023/09/05 04:40

tweet.html.erbのファイルも追加いたしました。 確認いただけますでしょうか
winterboum

2023/09/05 10:35

> Likedから何も変化ありませんでした。 リロードしても Likedの表示ということですね。 すると destroyに行ってないかな。 log でmethodが GET になってるか DELETE になってるかみてください
you_your

2023/09/05 11:45 編集

返信ありがとうございます。 * log でmethodが GET になってるか DELETE になってるかみてください -logは DELETE になっていると思います こちらにroutesを貼らせていただいても大丈夫でしょうか? こちらがroutesになります→(https://gyazo.com/9af6d2492c4f7974582b1333ebc7bb53)
you_your

2023/09/05 11:43 編集

"<%=link_to "Liked", tweet_likes_path(tweet.id), data: { turbo_method: :delete }, class: "tweet_likes" , remote: true %>" ルーティングを tweet_like_pathに変更するとエラーが出てしまします。 こちらがエラーです→(https://gyazo.com/dc959f53c0a6f9d89fc89bdd871317ac)
winterboum

2023/09/05 11:47

> -logは DELETE になっていると思います でないだろう、と推定しているので、確認してほしいのです。
winterboum

2023/09/05 11:49

エラーも画像でなく textで貼ってほしいな。 検索もコピペもできないから厄介
you_your

2023/09/05 12:16

エラーは解消できているので大丈夫です。
guest

回答1

0

ベストアンサー

あぁ、、、
tweetのIDだけしか渡してないから、ですね。Like も渡して下さい。
tweet_likes_path では DELETE の pathではない
tweet_like_path は DELETE(とGETの)pathだが、tweet_like_path(tweet.id) では LikeのIDが渡っていないのでエラー

投稿2023/09/05 11:57

winterboum

総合スコア23645

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

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

you_your

2023/09/05 12:19

理解不足なのですが、こちらの記述で大丈夫でしょうか? ``` <% if user_signed_in? && tweet.liked_by?(current_user)%> <%=link_to "Liked", tweet_like_path(tweet.id, like.id), data: { turbo_method: :delete }, class: "tweet_likes" , remote: true %> <% else %> <%=link_to "Like", tweet_likes_path(tweet.id), data: { turbo_method: :post }, class: "tweet_likes" , remote: true %> <% end %> ```
you_your

2023/09/05 12:27

エラーになってしまいました。。 ``` NameError in Tweets#index Showing /home/asami/projects/cafe/app/views/likes/_like.html.erb where line #2 raised: undefined local variable or method `like' for #<ActionView::Base:0x0000000000f5c8> Extracted source (around line #2): 1 2 3 4 5 <% if user_signed_in? && tweet.liked_by?(current_user)%> <%=link_to "Liked", tweet_like_path(tweet.id, like.id), data: { turbo_method: :delete }, class: "tweet_likes" , remote: true %> <% else %> <%=link_to "Like", tweet_likes_path(tweet.id), data: { turbo_method: :post }, class: "tweet_likes" , remote: true %> <% end %> ```
winterboum

2023/09/05 12:30

like 未定義だ って言ってますね。 tweet.likes から current_user のものを取り出しましょう
you_your

2023/09/05 12:42 編集

tweet.likes から current_user のものを取得するコードを修正すると無事 Like→Liked、Liked→Likeに変化しました!!!!!! とても感動です… 長時間お付き合いいただいたのと解決頂きとても感謝しております。 winterboumさんのようになりたいですが、なぜそのようにすぐ解決できるのでしょうか? MVCをしっかり理解していればわかりますか?
winterboum

2023/09/05 13:13

コンピューターは誤動作しません。期待通りに動かないのはプログラムの問題です。 ということを肝に命じておく、ってことですね。 エラーメッセージから逃げないこと、修羅場をたくさん潜ること、 自分がCPUになってプログラムを動かしてみること あたりかなぁ、、、
you_your

2023/09/06 06:29

返信遅くなり申し訳ありません。 エラーメッセージから逃げないこと、修羅場をたくさん潜ること -こちらは今私の課題なので逃げていたらスキルアップは無理だなと体感しております。  エラーを見ると心が揺らぎますがエラーを味方にしていきたいなと思います。 自分がCPUになってプログラムを動かしてみること -とても深いなと思いました。自分がCPUになって動かしてみる発想はなかったのでどちらも肝に銘じてこれからも頑張りたいと思います!
winterboum

2023/09/06 07:42

エラーを味方!!! です
you_your

2023/09/08 03:33

承知しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問