🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

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

Ruby on Rails

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

1回答

1104閲覧

DMの通知機能でNoMethodErrorが出る。

kokemaru2427

総合スコア8

Ruby

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

Ruby on Rails

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2021/03/03 03:29

編集2021/03/03 04:17

前提・実現したいこと

プログラミングスクールに通うプログラミング初心者です。
現在、ruby on rails でイベント投稿アプリを開発しています。
このイベント投稿アプリでは、DM機能があります。
今回は、DMをしたらDMをされた人に通知がいくようなシステムを作りたいと考えています。

また、こちらのリンクをほとんど同じように参考にさせていただきました。
DM通知機能の参考

しかし、ある程度の意味を理解し参考通りに実装したつもりだったのですが、エラーが出てしまいました。
(通知機能のindexページにアクセスしたところでエラー)

発生している問題・エラーメッセージ

NoMethodError in Notifications#index undefined method `visitor' for #<Notification::ActiveRecord_AssociationRelation:0x00007f963a925720> Extracted source (around line #1): <% visitor = notification.visitor %> #ここでエラー <% visited = notification.visited %> <div> <%= link_to user_path(visitor) do %> <%= visitor.name %>さんが <% end %>

該当のソースコード

(routes.rb)

Rails.application.routes.draw do get 'notifications/index' devise_for :users root to: 'home#top' resources :users resources :events do resources :comments, only: :create resources :entries, only: [:index, :new, :create] resource :favorites, only: [:create, :destroy] collection do get 'search' end end resources :messages, only: :create resources :rooms, only: [:create, :show] resources :notifications, only: :index #通知機能 end

通知機能ののマイグレーションファイルです。

class CreateNotifications < ActiveRecord::Migration[6.0] def change create_table :notifications do |t| t.integer :visitor_id t.integer :visited_id t.integer :room_id t.integer :message_id t.string :action t.boolean :checked t.timestamps end end end

(messages.controller.rb)チャットのメッセージのコントローラーです。

class MessagesController < ApplicationController before_action :authenticate_user! def create if Invite.where(user_id: current_user.id, room_id: params[:message][:room_id]).present? @message = Message.new(message_params) @room = @message.room if @message.save @roommembernotme = Invite.where(room_id: @room.id).where.not(user_id: current_user.id) @theid=@roommembernotme.find_by(room_id: @room.id) notification = current_user.active_notifications.new( room_id: @room.id, message_id: @message.id, visited_id: @theid.user_id, visitor_id: current_user.id, action: 'dm' ) if notification.visitor_id == notification.visited_id notification.checked = true end notification.save if notification.valid? redirect_to "/rooms/#{@message.room_id}" end else redirect_back(fallback_location: root_path) end end private def message_params params.require(:message).permit(:user_id, :body, :room_id).merge(user_id: current_user.id) end end

(notifications_controller.rb)通知機能のコントローラーです。

class NotificationsController < ApplicationController def index @notifications = current_user.passive_notifications end end

(user.rb)ユーザーモデルです。#関係ないところは省略してます。

has_many :active_notifications, class_name: 'Notification', foreign_key: 'visitor_id', dependent: :destroy has_many :passive_notifications, class_name: 'Notification', foreign_key: 'visited_id', dependent: :destroy

(message.rb)メッセージのモデル

class Message < ApplicationRecord belongs_to :user belongs_to :room has_many :notifications, dependent: :destroy end

(room.rb)チャットルームのモデルです。

class Room < ApplicationRecord has_many :messages, dependent: :destroy has_many :invites, dependent: :destroy has_many :notifications, dependent: :destroy end

notification.rb通知機能のモデルです。

class Notification < ApplicationRecord default_scope -> { order(created_at: :desc) } belongs_to :room, optional: true belongs_to :message, optional: true belongs_to :visitor, class_name: 'User', foreign_key: 'visitor_id', optional: true belongs_to :visited, class_name: 'User', foreign_key: 'visited_id', optional: true end

(notifications/index.html.erb)通知機能のトップページ

<% notifications = @notifications.where.not(visitor_id: current_user.id) %> <% if notifications.exists? %> <%= render 'notifications', notification: notifications %> <% else %> <p>通知はございません</p> <% end %>

(notifications/_notifications.html.erb)通知機能のトップページ(render)

<% visitor = notification.visitor %> <% visited = notification.visited %> <div> <%= link_to user_path(visitor) do %> <%= visitor.name %>さんが <% end %> <% if notification.action=='dm' %> あなたにDMを送りました <% end %> </div>

試したこと

エラーメッセージから、visitorが定義されていないと判断したが、visitorを持ってくるには定義が必要なのかどうかが、わかりません。参考にさせていただいたサイトでは、特に定義を書いているようには見えなかったため定義は必要ないと考えました。
また、通知機能のコントローラーでbinding.pryをかけてみたところ
class NotificationsController < ApplicationController
def index
@notifications = current_user.passive_notifications
binding.pry
end
end

[1] pry(#<NotificationsController>)> params
=> <ActionController::Parameters {"_method"=>"get", "authenticity_token"=>"tNMX58xTfELHDEdSlTuCpjc4QxTvS6uPQ39lRwnFEUkgk3n1RjhgEhZorQk+Bo1Xn8a6MnWEOWjuOPbT65XyYA==", "controller"=>"notifications", "action"=>"index"} permitted: false>
[2] pry(#<NotificationsController>)> @notifications
Notification Load (0.6ms) SELECT notifications.* FROM notifications WHERE notifications.visited_id = 1 ORDER BY notifications.created_at DESC
↳ app/controllers/notifications_controller.rb:4:in `index'
=> [#<Notification:0x00007ff051c63010
id: 1,
visitor_id: 3,
visited_id: 1,
room_id: 4,
message_id: 26,
action: "dm",
checked: nil,
created_at: Tue, 02 Mar 2021 14:51:28 UTC +00:00,
updated_at: Tue, 02 Mar 2021 14:51:28 UTC +00:00>]

と出ました。メッセージコントローラーを移動して、通知コントローラーが動くため、コントローラーには問題はなく
コントローラーからビューの間でデータの受け渡しができていないと仮説は立てました。
しかし、定義しないといけないものがわかりませんでした。
ご教授いただければ幸いです。

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

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

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

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

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

guest

回答1

0

notifications/_notifications.html.erb は 1 件の Notification を表示する部分テンプレートですよね。

で,notifications/index.html.erb では each で繰り返しこの部分テンプレートを呼ぶわけではなく,render 一発で繰り返しこれを呼ぼうとしていますね?
その場合,rendercollection オプションを使うことになると思います。
https://railsguides.jp/layouts_and_rendering.html#%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B

エラーの直接の原因は,部分テンプレート側では notificationNotification オブジェクトであるという前提で visitor メソッドを呼んでいるのに,実際に渡されたものはそうではなかった,ということです。
試しに部分テンプレートで notification.class して,どんなクラスのオブジェクトが渡ってきたか見てみてください。

投稿2021/03/07 09:46

scivola

総合スコア2108

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問