1
0

More than 1 year has passed since last update.

[Rails]いいねしてくれたユーザに、新規投稿をメール通知する(開発環境編)

Last updated at Posted at 2023-08-16

きっかけ

経緯

就活中の選考での課題として
[投稿者のレビューにいいねをしたユーザに、その投稿者が新規でレビューしたときにメールでお知らせする機能]
の作成が出てきましたので、アウトプット用に記載いたします。

開発環境

Ruby 3.1.2
Rails 6.1.7.3

手順

この機能を実装するためには、以下の手順で行うことにします。

①モデルの設定

ユーザとレビュー、いいねのモデルを設定します。ユーザとレビュの関連付け、いいねとユーザ・レビューとの関連付けをします。

app/models/user.rb
class User < ApplicationRecord
  has_many :contents
  has_many :favorites
end
app/models/content.rb
class Content < ApplicationRecord
  belongs_to :user
  has_many :favorites
end
app/models/favorite.rb
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :content
end

②投稿者が新規でレビューを作成した時の処理

レビューが新たに作成されるたびに、その投稿者の過去レビューにいいねしたユーザのリストを取得します。

app/models/content.rb
class Content < ApplicationRecord
    # 以上に諸々の処理を記載

    # 新しいレビューがデータベースに保存された後に以下のメソッドが実行する。(コールバック)
    after_create :send_message_to_favorited_users
    
    private
    
    # いいねしたユーザのIDリストを取得するメソッド
    def send_message_to_favorited_users
      favorited_users = Favorite.where(content_id: self.user.contents.pluck(:id)).pluck(:user_id).uniq
      favorited_users.each do |user_id|
        user = User.find(user_id)
        # 投稿した本人にメールを送信しない
        unless user_id == self.user.id
          FavoritedUserMailer.new_content_message_email(user, self).deliver_now
        end
      end
    end
end
コールバックで処理

まず、after_createはActive Record モデル内で使用されるコールバックの1つです。レビューが新規作成された後に send_message_to_favorited_users メソッドが自動的に呼び出されるようにするためのものです。

過去にいいねしたユーザをリスト化する処理

次に、以下のコードの処理について

content.rb
favorited_users = Favorite.where(content_id: self.user.contents.pluck(:id)).pluck(:user_id)`

Favoriteモデルから、指定された条件に合致するレコードを取得しています。
今回の指定した条件は、content_idカラムでレビューしたユーザが投稿したレビューのIDリストに含まれているものです。つまり、レビューを「いいね」したレコードを取得しています。
さらに、.pluck(:user_id)で上記のクエリ結果(Favorite レコード)から、user_id カラムの値を取得しています。これにより、レビューを「いいね」したユーザーのIDリストを取得することができます。
最後に、favorited_users = で上記の手順で取得した「いいね」したユーザリストを、favorited_users変数に代入しています。
つまり、上記コードは簡単に言うと投稿者が作成したレビューの中で「いいね」されたレコードを抽出するためのものです。

リスト化したユーザにメール送信する処理
user = User.find(user_id)

先ほどの、favorited_users変数から「いいね」したユーザIDを使用して、対応するユーザをデータベースから取得します。

unless user_id == self.user.id
   FavoritedUserMailer.new_content_message_email(user, self).deliver_now
end

そして、投稿者を除外するunless文を用いて、投稿者以外にメールを送信します。

③通知メールの送信

取得したいいねユーザリストに対して、通知メールを送信する処理を行います。RailsではAction Mailerを使用してメールを送信できますので、メール文を決め、Action Mailerを設定します。

Action Mailerを生成する

まず、メール送信するために必要なApplicationMailerを継承するクラスは、generateコマンドから作成します。ターミナルで以下のコマンドを行います。

$ rails generate mailer FavoritedUserMailer

以上で、以下のフォルダ、ファイルが作成されました。

Running via Spring preloader in process 616
      create  app/mailers/favorited_user.rb
      create  app/mailers/application_mailer.rb
      invoke  erb
      create    app/views/favorited_user
      invoke  test_unit
      create    test/mailers/favorited_user_test.rb
      create    test/mailers/previews/favorited_user_preview.rb
メールの宛先や件名を指定する
app/mailers/favorited_user_mailer.rb
class FavoritedUserMailer < ApplicationMailer
  def new_content_message_email(user, content)
    @user = user
    @content = content
    mail(to: @user.email, subject: 'いいねしたユーザが新しいレビューを投稿しました!')
  end
end

 今回、いいねしたユーザに送るメールということでFavoritedUserMailerクラスnew_content_message_emailメソッドを作成します。
to(メールの送信先アドレス)を指定したり、subjectで件名を指定することできます。
※Railsのコントローラと似た形式でコーディングを行います。

さらに、下記のようにdefault from:...で差出人のメールアドレスを指定できます。

app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: 'totono-ru@saunar.com'
  layout 'mailer'
end
ビューの生成(メール内容の作成)

mailerで定義した変数はビューで使えます。今回はapp/views/favorited_user_mailerに例えば以下のようなメッセージを作成することができます。

<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
  </head>
  <body>
    <h1> <%= @user.name %> 様</h1>
    <h3>いつもご利用いただきありがとうございます。</h3>
    <p><%= @content.user.name %> さんが新しいレビューを投稿しました!</p>
    <p>詳細な内容を見るには以下のリンクをクリックしてください。</p>
    <p>レビュータイトル: <%= @content.title %></p>
    <a href="<%= content_url(@content) %>">新しいレビューを見る</a>
    <br>
    <p>以上です。</p>
    <p>今後ともご愛顧いただきますよう、よろしくお願いいたします。</p>
  </body>
</html>
ビューでURLを生成する方法
<a href="<%= content_url(@content) %>">新しいレビューを見る</a>

リンク先としてURLを記載するには、以下の記事を参考にして設定変更を行いました。

メール送信のトリガーの確認
app/models/content.rb
    FavoritedUserMailer.new_content_message_email(user, self).deliver_now

今回は先ほど作成したcontentモデルで作成した以上のコーディングをトリガーにして送信を行います。

④letter_opener_webでメールをブラウザでプレビューする

開発環境では、テストなどでメールを送信する代わりにデフォルトのブラウザでプレビューする方が楽です。それでは、以下に手順を記載します。

導入手順

まずhはGem導入から

Gemfile.rb
group :development do
  gem 'letter_opener_web', '~> 1.0'
end

次に、routes.rbにletter_opener用のルーティングを追加します。

config/routes.rb
Rails.application.routes.draw do
  # 下記を追加
  mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
  # 既存のルーティングが以下に続く
end

そして、

config/environments/development.rb
require 'active_support/core_ext/integer/time'

Rails.application.configure do
  ...

  # 下記を追加
  config.action_mailer.delivery_method = :letter_opener_web
end

以上で、letter_opener_webの導入は完了しました。

送信メールの内容を確認

メール送受信を確認するには、http://localhost:3000/letter_opener/のようにrootにletter_opener/追加してアクセスすると下記のような画面が表示されていれば設定は完了しています。
LetterOpenerWeb.jpg

終わりに

以上で、いいねしたユーザのリスト化からメール送信、開発環境でのメールブラウザ確認までを行いました。
メール設定など基本を改めて勉強できてよかったです。誤りがありましたらコメントいただけると幸いです!
最後まで閲覧いただき、ありがとうございました。

参考にした記事

以下の記事を参考に作成させていただきました。ありがとうございます!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0