1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsで全ユーザーにメールを送信する

Last updated at Posted at 2021-05-13

はじめに

メールの送信機能を初めて実装したので、躓いたところや実装方法をメモとして残しておきます。
質問回答アプリで新規質問が投稿された際に、全員に対して質問があった旨をメールで通知する。

Action Mailer

Action Mailerを使うと、アプリケーションのメイラークラスやビューでメールを送信することができる。メイラーの動作はコントローラときわめて似通っている。メイラーはActionMailer::Baseを継承し、app/mailersに配置され、app/viewsにあるビューと結び付けられる。

Mailer作成手順

  1. メイラーを作成
rails g mailer QuestionMailer
app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: "from@example.com"
  layout 'mailer'
end

開発環境でメール送信を確認する方法

mailcatcher

シンプルなsmtpサーバを立てて、送信されたメールをブラウザ上で確認できるようにしてくれる。
(cloud9でmailcatcherを実行しようとしたら、うまく実行出来ず原因はcloud9ではないかと考えられる。なので、メール確認のために代わりにletter_opener_webを使用しました。)

letter_opener_web

ローカル開発環境で送信したメールをブラウザ上で確認することができる

http://localhost:3000/letter_openerにアクセスすることで送信されたメールを確認できる

cloud9で使う方法

  1. gemを追加
Gemfile
group :development do
  gem 'letter_opener_web'
end
  1. ルーティング
config/routes.rb
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
  1. config デフォルトURLを指定(cloud9バージョン)
config/environments/development.rb
config.action_mailer.default_url_options = { host: 'myapp.c9users.io/', port: $PORT, protocol: 'https'  }
config.action_mailer.delivery_method = :letter_opener_web

質問があった際に全員に対して質問があった旨をメールで通知する

app/mailers/question_mailer.rb
class QuestionMailer < ApplicationMailer
  default from: 'qanda@example.com'    
  def creation_email(user)
    @user = user
    mail(subject: '新規質問です',to: user.email, from: "qanda@example.com")
  end 
  def self.creation_email_questions
    @users = User.all
    @users.each do |user|
      QuestionMailer.creation_email(user).deliver_now
    end 
  end
end
app/controllers/questions_controller.rb
  def create
    @question = current_user.questions.new(question_params)
    if @question.save
      QuestionMailer.creation_email_questions
      redirect_to questions_url, notice: "質問を「#{@question.title}」投稿しました。"
    else
      render :new
    end
  end

躓いたところ

これでも、全ユーザーにメールを送信することは可能だが、考え方が少し複雑な上にメイラーのビューで質問のタイトルや内容を表示するために@question使えない。あと、メーラにクラスメソッドを定義するやり方はあまりやらない。

改善するには

メーラのクラスメソッドで定義されている全ユーザーを取り出す処理をquestions_controllerで定義すれば、メーラにクラスメソッドを定義しなくても良くなる!

app/controllers/questions_controller.rb
  def create
    @question = current_user.questions.new(question_params)
    if @question.save
      User.all.each do |user|
        QuestionMailer.with(user: user, question: @question).creation_email.deliver_now
      end
      redirect_to questions_url, notice: "質問を「#{@question.title}」投稿しました。"
    else
app/mailers/question_mailer.rb
  def creation_email
    @user = params[:user]
    @question = params[:question]
    mail(subject: '新規質問',to: @user.email, from: "qanda@example.com")
  end

このようにwith(question: @question)と書くことでメイラーのアクションでparams[:question]が使えるようになり、ビューでも@questionが使えるのでメールの内容を表示することができるようになる。あとはビューを編集して完成。

1
0
1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?