🚀

Rails|グループ作成④(通知メールの送付:修正版)

2023/08/06に公開

前回の記事のメール作成方法がわかりにくかったので、再掲します。
https://zenn.dev/airiin/articles/d90bb1d6cdebd8

前提

こちらの記事の続きになります。
https://zenn.dev/airiin/articles/6ecc7f19dcd467

Mailer の作成

$ rails g mailer EventMailer

サーバーの設定

config/environments/development.rb
config.action_mailer.raise_delivery_errors = true

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'gmail.com',
    user_name: ENV['MAIL_ADDRESS'],
    password: ENV['MAIL_PASSWORD'],
    authentication: 'plain',
    enable_starttls_auto: true
  }

Gem dotenv-rails をインストールし、
.env ファイルを作成し、
環境変数を代入済み。

Mailer の編集

application_mailer.rb は変更なし。

event_mailer.rb
  def send_notification(member, event)
    @group = event[:group]
    @title = event[:title]
    @body = event[:body]

    @mail = EventMailer.new()
    mail(
      from: ENV['MAIL_ADDRESS'],
      to: member.email,
      subject: 'New Event Notice!'
      )
  end

  def self.send_notifications_to_group(event)
    group = event[:group]
    group.users.each do |member|
      EventMailer.send_notification(member, event).deliver_now
    end
  end

send_notification
最初に書いてるこのメソッドは、下の self.send_notifications_to_group の中で使われています。また、下のメソッドは後に作成する event_notices_controllercreateメソッド で使われています。

まず、send_notificationメソッドから見ていきます。
このメソッドは引数(member) に対して、通知メールを作成し、送付する役割を持っています。
後に作成する send_notification.text.erbというビューに対応しています。このビューはメール本文です。

@group, @title, @body
これらは、メール本文のビューに変数を渡すためのものです。

@mail = EventMailer.new
この部分で EventMailer の新しいインスタンスを作成し、@mail に代入しています。

mail(from: ENV['MAIL_ADDRESS'],to: member.email,subject: 'New Event Notice!')
この部分は、メールの送信元、メールの送信先、件名を指定しています。

次に、下のメソッド self.send_notifications_to_group について確認します。
このメソッドは、イベント情報を受け取り、そのイベントが関連するグループのすべてのメンバーに対して、メール通知を送る役割があります。

EventMailer.send_notification(member, event).deliver_now
この部分で、上のメソッドを呼び出しています。
また、.deliver_now で即座にメールを送信しています。

コントローラの作成

次に、event_notices_controller を作成します。

$ rails g controller event_notices
event_notices_controller.rb
  def new
    @group = Group.find(params[:group_id])
  end

  def create
    @group = Group.find(params[:group_id])
    @title = params[:title]
    @body = params[:body]

    event = {
      :group => @group,
      :title => @title,
      :body => @body
    }

    EventMailer.send_notifications_to_group(event)
    render :sent

  end

  def sent
    redirect_to group_path(params[:group_id])
  end

newアクション
後に作成する event_notices/new ページで使用するインスタンス変数を定義しています。

createアクション
newアクションで入力した情報を元に、新しいメールを作成しています。

@title, @body
これらは newアクションで入力された内容が代入されています。

event = { :group => @group, :title => @title, :body => @body }
ここでは、必要なデータを eventというハッシュに代入しています。このハッシュは次にのステップでメール送信メソッドに渡されます。

EventMailer.send_notifications_to_group(event)
event_mailer で定義した send_notifications_to_groupメソッドを使用しています。
引数に、先ほど作成した eventハッシュを渡しています。
この段階で、メールが作成・送信されます。

render :sent
sentビューにレンダリングされます。

ルーティングの設定

event_noticesコントローラで、new, create, sentアクションを作成しました。それらのルーティングを設定します。

congif/routes.rb
  resources :groups, only: [:new, :index, :show, :create, :edit, :update] do
    resource :group_users, only: [:create, :destroy]
    resources :event_notices, only: [:new, :create]
    get "event_notices" => "event_notices#sent"
  end

event_notices/new ビューの作成

event_notices/new.html.erb
<div class="container">
  <div class="row justify-content-center">
    <div class="col-6">

      <h1>Event Mail</h1>

      <%= form_with url: group_event_notices_path(@group), method: :post, local: true do |f|  %>

        <div class="form-group">
          <%= f.label :title %>
          <%= f.text_field :title, class: "form-control" %>
        </div>

        <div class="form-group">
          <%= f.label :body %>
          <%= f.text_area :body, class: "form-control" %>
        </div>

        <div class="form-group d-flex justify-content-end">
          <%= f.submit "Send", class: "btn btn-success" %>
        </div>

      <% end %>

    </div>
  </div>
</div>

event_notices/sent ビューの作成

event_notices/sent.html.erb
<div class="container">
  <div class="row justify-content-center">
    <div class="col-6">

      <h1>送信が完了しました</h1>

      <p>内容は以下のとおりです</p>

      <h2>[タイトル]</h2>
      <p><%= @title %></p>

      <h2>[本文]</h2>
      <p><%= @body %></p>

    </div>
  </div>
</div>

event_mailer/send_notification ビューの作成

event_mailer.send_notification.text.erb
============================================

New event from <%= @group.name %> !!

============================================

Title:
<%= @title %>

Details:
<%= @body %>

Discussion