かっちゃんのプログラミング奮闘記

このブログは、僕がプログラミング学習をしていく上で、知識のインプットを図るためのアウトプット場所として活用している場所です。

【Rails】通知機能のメソッドを覚えておく

今回は、通知機能の実装で学んだことと知識の定着をはかるためのアウトプットをメモ書き程度にして行きたいと思います。

実装内容

自分が投稿した内容にコメントが来たら通知が来る通知機能の実装

完成画面

f:id:kazuki13070311:20210908222014p:plain
通知画面

前提

  • ユーザー機能実装済み(Userモデル)
  • 投稿機能実装済み(Postモデル)
  • コメント機能実装済み(Commentモデル)

内容

通知機能はnotificationモデルを作成して実装した。

f:id:kazuki13070311:20210908222805p:plain
通知モデル

通知機能のコード

  • comments_controller.rb
def create
  @comment = Comment.new(params_comment)
  @post = @comment.post
  @comment.user_id = current_user.id
  if @comment.save
    @post.create_notification_comment!(current_user, @comment.id)
    redirect_back(fallback_location: root_path, notice: '投稿が完了しました。')
  else
    redirect_back(fallback_location: root_path, notice: '投稿に失敗しました。')
  end
end


  • comment.rb
def create_notification_comment!(current_user,comment_id)
  temp_ids = Comment.select(:user_id).where(post_id: id).where.not(user_id: current_user).distinct
  temp_ids.each do |temp_id|
    save_notification_comment!(current_user, comment_id, temp_id['user_id'])
  end
  save_notification_comment!(current_user, comment_id, user_id) if temp_ids.blank?
end

def save_notification_comment!(current_user, comment_id, visited_id)
  notification = current_user.active_notifications.new(
    post_id: id,
    comment_id: comment_id,
    visited_id: visited_id,
    action: 'comment'
  )
  if notification.visiter_id == notification.visited_id
    notification.checked = true
  end
  notification.save if notification.valid?
end

以下で詳しく見ていきます。

コメントコントローラーのsaveでコメント保存ができた後に下記コードで通知メソッドを呼び出して実行している。

@post.create_notification_comment!(current_user, @comment.id)

(current_user, @comment.id)で現在のユーザー情報とコメントIDをメソッドに渡している。

@post = @comment.postここでcommentインスタンスに紐づいたpostモデルを引っ張ってきて@postに格納している。
@post.create_notification_comment!postモデルに記述してあるcreate_notification_comment!メソッドを呼び出す。

where.not(user_id: current_user)ここで現在のユーザー(自分)のユーザーIDは取得しない様にし、where(post_id: id)で投稿IDを選択し、 select(:user_id)でユーザーIDのカラムだけ選択しています。

その結果、自分以外で投稿にコメントしているユーザーを取得してtemp_idsに格納している。

distinctメソッドで重複する同じレコードを削除し1つだけにしている。

temp_ids = Comment.select(:user_id).where(post_id: id).where.not(user_id: current_user).distinct


複数コメントが来た場合、毎回通知を送る時のレコードを作成する。

  temp_ids.each do |temp_id|
    save_notification_comment!(current_user, comment_id, temp_id['user_id'])
  end
  ・
  ・
  ・
  def save_notification_comment!(current_user, comment_id, visited_id)
    notification = current_user.active_notifications.new(
      post_id: id,
      comment_id: comment_id,
      visited_id: visited_id,
      action: 'comment'
    )
    ・
    ・
    ・
  end

save_notification_comment!(current_user, comment_id, temp_id['user_id'])の引数の部分をdef save_notification_comment!(current_user, comment_id, visited_id)の引数(current_user, comment_id, visited_id)に格納される。



現在のユーザーとコメントIDと通知を受信した人のIDとcommentアクションをレコードに入れて作成している。


初めて投稿にコメントが来た場合に通知レコードを発行するメソッドを実行する。

if temp_ids.blank?temp_ids内にオブジェクト情報が入っていない場合にメソッドを実行する後置if文で書いている。

save_notification_comment!(current_user, comment_id, user_id) if temp_ids.blank?