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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

解決済

2回答

1412閲覧

「いいね」機能を実装したいが、ビューファイルで「NoMethodError in Messages#index」が出てしまいます。

skem

総合スコア1

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/09/25 09:36

編集2020/09/27 01:13

こちらのURLを参照しながら、「いいね」機能の実装を試みています。
https://qiita.com/nojinoji/items/2c66499848d882c31ffa

しかし、「いいね」機能を実装しようとしているビューで下記のエラーが出てしまっています。
イメージ説明

該当するエラー(22行目)で「message_likes_path」を「message_like_path」に変えてみたり、「,method: :post」などを加えてみたりしたのですが、エラーが変わりませんでした。
ビューファイルは下記のようになっています。

%h3 いいね件数: #{@message.likes.count} - if current_user.already_liked?(@message) = button_to 'いいねを取り消す', message_like_path(@message), method: :delete - else = button_to 'いいね', message_likes_path(@message) %h2 いいねしたユーザー - @message.liked_users.each do |user| %li= user.email = link_to "ホームへ戻る", messages_path

コントローラーは下記です。
インスタンス変数の使い方が違うのかなとも思ったのですが、エラーは変わりませんでした。

class MessagesController < ApplicationController def index @message = Message.new @messages = current_user.messages end def create @message = current_user.messages.new(message_params) if @message.save redirect_to user_messages_path(current_user), notice: 'メッセージが送信されました' else @messages = current_user.messages flash.now[:alert] = 'メッセージを入力してください。' render :index end end private def message_params params.require(:message).permit(:content, :image).merge(user_id: current_user.id) end end

アドバイスを頂ければ幸いでございます。


【9/26更新】
上記エラー文に「undefined method `message_likes_path'」 とあったので、pathを調べるために、rails routesを確認しました。

Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new user_session POST /users/sign_in(.:format) devise/sessions#create destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit user_password PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update POST /users/password(.:format) devise/passwords#create cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel new_user_registration GET /users/sign_up(.:format) devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit user_registration PATCH /users(.:format) devise/registrations#update PUT /users(.:format) devise/registrations#update DELETE /users(.:format) devise/registrations#destroy POST /users(.:format) devise/registrations#create root GET / messages#index user_message_likes POST /users/:user_id/messages/:message_id/likes(.:format) likes#create user_message_like DELETE /users/:user_id/messages/:message_id/likes/:id(.:format) likes#destroy user_messages GET /users/:user_id/messages(.:format) messages#index POST /users/:user_id/messages(.:format) messages#create edit_user GET /users/:id/edit(.:format) users#edit user PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update

prefixに「user_message_likes」とあったので、「message_likes_path」を「user_message_likes_path」に変更しました。また追加で、引数を最上部の配列の「m」に変更し、viewファイルを下記のようにしました。

.messages - @messages.each do |m| .message .takerface %img{alt: "userface", 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"}/ .contents .takername = m.user.name + " さんへ" .letter - if m.content.present? %p.lower-message__content = m.content .credo #仕事好き #親身心 #人生を変える .like %h3 いいね件数: #{m.likes.count} - if current_user.already_liked?(m) = button_to 'いいねを取り消す', user_message_like_path(m), method: :delete - else = button_to 'いいね', user_message_likes_path(m) %h2 いいねしたユーザー - m.liked_users.each do |user| %li= user.email = link_to "ホームへ戻る", messages_path

エラーが少し変わって下記のようになりました。
イメージ説明


【9/27更新】

モデルのコードは下記となります。上から「Message」「User」「Like」です。

class Message < ApplicationRecord belongs_to :user validates :content, presence: true has_many :likes has_many :liked_users, through: :likes, source: :user end
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable validates :name, presence: true, uniqueness: true has_many :messages has_many :likes has_many :liked_messages, through: :likes, source: :message def already_liked?(message) self.likes.exists?(message_id: message.id) end end
class Like < ApplicationRecord belongs_to :message belongs_to :user validates_uniqueness_of :message_id, scope: :user_id end

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

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

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

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

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

guest

回答2

0

/users/:user_id/messages/:message_id/likes/:id(.:format)となっているので、user_id,message_id,likeのidの3つを渡さなければなりません。

- if current_user.already_liked?(m) - like = current_userがmにしているlikeを取り出す = button_to 'いいねを取り消す', user_message_like_path(current_user.i,m.id,like.id), method: :delete

投稿2020/09/26 13:55

winterboum

総合スコア23329

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

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

skem

2020/09/27 01:00

ありがとうございます!すみません、「- like = current_userがmにしているlikeを取り出す」というのは、どのように記述すれば良いかご教示いただけませんでしょうか?? 下記2行目のように変更してみたのですが、SyntaxErrorになってしまいまして。。 ``` - if current_user.already_liked?(m) - like = current_user.liked_messages.each do |message| = button_to 'いいねを取り消す', user_message_like_path(current_user.i,m.id,like.id), method: :delete ```
winterboum

2020/09/27 01:05

モデルのcodeを載せてください
skem

2020/09/27 01:14

質問欄を編集し、モデルを掲載させて頂きました。
winterboum

2020/09/27 05:52

current_user.likes.find_by(message_id: m.id)
skem

2020/09/27 06:23

ありがとうございます!
guest

0

自己解決

ありがとうございます!下記で通りました!

- if current_user.already_like_this?(m) - like = current_user.likes.find_by(message_id: m.id) = button_to 'いいねを取り消す', user_message_like_path(current_user.id,m.id,like.id), method: :delete - else = button_to 'いいね', user_message_likes_path(current_user.id,m.id), method: :post

投稿2020/09/29 07:36

skem

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問