【rails】Mailerの作成

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

Mailerの作成

app/mailers/application_mailer.rbを確認してみる

class ApplicationMailer < ActionMailer::Base
  default from: 'from@example.com'
  layout 'mailer'
end

上記のようにActionMailer::Baseを継承しているため、少しのコードで動かすことができる

項目意味
default from:‘from@example.com’からメールを送信する、という意味
layoutviews/layouts/mailer.htmlhaml、mailer.text.hamlをテンプレートしてメールを作成する、という意味


自分でmailerを作成してみる

app/mailers/relationship_mailer.rbを作成する

relationship_mailer→フォローされたときに通知を送る

class RelationshipMailer < ApplicationMailer

end

準備として、ApplicationMailerを継承したクラスを作る


メソッドを定義する

controllerのときと同じように、relationship_mailer.rbにメソッドを定義していく

メソッドひとつひとつに対してviewも必要となる
(メールの本文が書いてあるviewのこと)


フォローされたとき(new_follower)

メールの送り先、メールのタイトルを設定する

  def new_follower
    mail to: 'メールアドレス@email.com', subject:'メールのタイトル'
  end

これでメールが送れるようになるが、実際は以下のようになる

class RelationshipMailer < ApplicationMailer
  def new_follower(user, follower)
    @user = user
    @follower = follower
    mail to: user.email, subject:'【お知らせ】フォローされました'
  end
end

第一引数を使って、そのときどきのuser.emailにメールが送信されるようにする

使い方)RelationshipMailer.new_follower(User.first)


viewを用意する

views/relationship_mailerのフォルダを作成する

続けて、new_follower.html.hamlのファイルを作成する

%p #{@user.email}さん
%p 以下のユーザーにフォローされました。

= link_to 'プロフィールを確認する', account_url(@follower)

インスタンス変数を定義しているので、viewで@user@followerを使うことができる

= link_toで、followerのプロフィールへ遷移するリンクが貼れる

メソッド名new_followerと同じ名前のviewにしておく


pathじゃなくてurlを指定する理由

account_url(@follower)の記述について。

users_path => '/users'
users_url => 'http://localhost:3000/users'
  • メール(別アプリ)を開いているので、urlをきっちり指定しないと該当のページに飛ばない
  • 同じアプリケーション内でページ遷移するときはpathでも良い

メールを送付してみる

rails cでコンソール画面を立ち上げる

irb(main):001:0> RelationshipMailer
=> RelationshipMailer

上記のように返ってこれば準備完了


試しにメールを送付してみる

RelationshipMailer.new_follower(User.first, User.second).deliver_now

メールの送り主、送り先を始め、メールが送付されたことは分かる
(読めないけど)


送信した内容を見やすくする

Gemfileに以下を追加する

group :development do
 # 中略
  gem 'letter_opener', '1.7.0'
  gem 'letter_opener_web', '~> 1.0'
end

送ったメールの内容が全然わからないので、わかりやすくしてくれる

letter_opener_webは、Web上でメールの中身が見れるようにするもの
(役割としてはほぼ同じ)

 ※バージョンは講義内容に合わせて指定

bundle install

インストールが完了したらroutes.rbを開いて、以下を追加する

Rails.application.routes.draw do

  mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?

【意味】
development環境であれば、’/letter_opener’のurlにアクセスすると「LetterOpenerWeb」の内容が見れるようになる

letter_opener_webドキュメントに載っているコードをそのままコピー


config/environments/development.rbを開く

以下のようにmailerについて書かれている部分がある

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  config.action_mailer.perform_caching = false
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

上記の続きに↓のコードを追加する

  config.action_mailer.delivery_method = :letter_opener_web
  config.action_mailer.perform_deliveries = true

letter_opener_webドキュメントに載っているコードをそのままコピー


letter_openerが動いているか確認する

サーバーを再起動rails sする

http://localhost:3000/letter_opener」を開く

このとき、先ほどと同じようにコンソール画面からメールを送るとエラーになってしまう


コールバックを使う

コールバックとは

イベントが実行されたタイミングでメソッドを実行すること

イベント例)

  • バリデーションが実行されたとき
    • before_validation
  • データが保存・更新・削除されたとき
    • before_create
    • after_save
    • before_destroy など

コールバックを使い、誰かがフォローされたタイミングでメールを送信する

relationship.rbを開く

class Relationship < ApplicationRecord
  belongs_to :follower, class_name: 'User'
  belongs_to :following, class_name: 'User'

  after_create :send_email

  private
  def send_email
    RelationshipMailer.new_follower(following, follower).deliver_now
  end
end
  1. relationshipcreateが実行される
  2. インスタンスが作成されたあと(after)、send_mailを実行

これにより、新たなフォロー関係(インスタンス)ができるたびにメールが送信されるようになる


controllerよりmodelに書いたほうがいい理由

follows_controller.rbよりrelationship.rb(model)に書いたほうがいい理由

  • followsの関係を作っているcontrollerが複数ある場合、すべてでsend_mailを書かなくちゃいけなくなる
  • modelで、relationshipのコールバックを定義しておくと抜け漏れがなくなる

実際フォローすると、http://localhost:3000/letter_openerではこんな表示になる

letter_openerもちゃんと動いている

#DAY9