質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.23%

  • Ruby

    5467questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    5366questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Railsで特定のユーザーに定期的にメールを送信する方法を教えてください。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 54

koume

score 152

Rails5.1.3でWebアプリケーションの勉強をしながら、実際に公開することを目指して制作しています。
その中の機能として特定のユーザーに対してcronで定期的にメールを送信するようにしたいのですが、あやふやなので
教えてください。 自分なりの解釈では以下の順番でコードを記述すればと思っていますが違うような感じもしています。

1,Action Mailerの設定    (config/development.rb)
2,メーラーの生成    (rails g mailer notice sendmail)
3,生成されたメーラーを編集する。    (app/mailers/notice_mailer.rb なのか app/lib/notice_mailer.rb なのか)
4,メール本文のデザインをする。   (notice_mailer/sendmail.html.erb)
5, cronに登録する。  (config/schedule.rb)

こんなイメージを持っていますが、libディレクトリにファイルをおいてcronで実行するのかな?などよくわかりません。
また、ユーザーを特定するコードをnotce_mailer.rbに記述してもいいものかどうかもよくわからないのです。
一応、コードは以下になっています。

1,Action Mailerの設定

config/development.rb

Rails.application.configure do
・・・中略・・・
config.action_mailer.delivery_method = :smtp
config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
  address: 'smtp.examples.com',
  port: 587,
  user_name: 'hogehoge',
  password: 'secret',
  domain: 'examples.com'
}
end
2, メーラーの生成

$ rails g mailer notice sendmail
3, 生成されたメーラーを編集する。(libフォルダに記述するのか?、そのままこのファイルに記述するのか?)

app/mailers/notice_mailer.rb なのか app/lib/notice_mailer.rb なのかどちらに記述するのでしょうか?

class NoticeMailer < ActionMailer
  default from: "from@example.com"

  def sendemail
   @user = Customer.where(gender: 1)
    @user.each do |name|
      mail to: name.email, subject: "ありがとうございました。"
      render "sendmail"
    end
  end
end
4,メール本文のデザインをする。

notice_mailer/sendmail.html.erb

<%= @user.username %>さま

このたびは、ご利用ありがとうございました。
5, cronに登録する。

config/schedule.rb

every 1.days, at: "7:00 am", roles: [:app] do
  runner "NoticeMailer.sendmail.deliver"
end


ネットでいろいろ調べてこんな感じで記述すればいいかと思いましたが、この記述方法で genderが1のユーザーにのみ
定期的にメール送信できるのでしょうか?
しかし、メーラーの生成を $ rails g mailer notice sendmail で行うと メーラーはapp/meilersフォルダの配下に
できるのでそこにコードを記述していけばいいのでしょうか?それともそれを無視して(削除して)libフォルダに
メーラーを記述するのでしょうか?

どなたか修正箇所も含めて教えていただけないでしょうか?宜しくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

まず NoticeMailer の置き場所ですが,ジェネレーターがせっかくファイルを用意してくれたのに,わざわざそれを別の場所に移すのはレールから外れることになります。よって,ファイルの場所はそのまま。

メイラーアクションの名前が sendmail では何のことやら分からないので,もう少し中身を表した名前がいと思います。
(何がいいかは分かりませんが,お礼なら thanks とか,ただの挨拶なら greeting とか,なんかローマ字で考えるとか)

ユーザーのループを回すのはアクションのメソッドの外でします。
メソッドの引数に User オブジェクトを渡してやります。

つまり,

class NoticeMailer
  # 中略

  def sendmail(user)
    # 略
  end
end

と。

なお,

@user = Customer.where(gender: 1)

などと書いていますが,こういうときの変数名は複数形にしましょう。でないとコードが読みにくく,バグを生みやすく,デバッグしにくくなります。

メイラーアクションの名前とビューテンプレートの名前を一致させておけば render は不要です。

ここまで出来たら,まず rails console で

user = User.first # なんかのユーザーを一つもってくる
NoticeMailer.sendmail(user).deliver_now

とかなんとかして,メールが飛ぶことを確認しましょう。

次に,gender が 1 の全 Custormer についてメール送信するコードですが,私なら Customer モデルに書いちゃうところですが,これが Rails の正しい流儀かどうか自信がありません。(Rails マスターのみなさん,ツッコミお願いします)

もしそれでいいとすると,

class Customer < ApplicationRecord
  # 略

  def self.thanks_to_all
    where(gender: 1).each do |user|
      NoticeMailer.sendmail(user).deliver_now
    end
  end
end

みたいな感じでしょうか。
もちろん,大量にメールするなら deliver_now じゃなくて云々,という話はあります。

ここまで出来たら,やはり rails console で

Customer.thanks_to_all

とかやって,該当者全員にメールが飛ぶか確認します。

次は cron ですね。
config/schedule.rb と書いてあるので,whenerver gem を使うのでしょうか?
whenerver の使い方は大丈夫ですか。

whenever がよく理解できるまでは,1 分ごとに何か小さなことをやらせてみて,期待どおりに動くかどうか,試してみるのがいいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/06 17:31

    回答ありがとうございます。 render "sendmail" の1行は不要なのですね。それとcronを使って
    定期的に処理を行いたいことが他にもあるのでwhenerverについても試してみます。
    「ユーザーのループを回すのはアクションのメソッドの外でします。」とありますが、どこに
    記述すればいいのかわからないので教えていただけませんでしょうか?
    自分の場合、def sendemailの中に記述していますが、レコードの検索、ループを回すのはどこに
    コードを記述すればいいのでしょうか?教えていただけませんでしょうか?

    キャンセル

  • 2018/01/06 17:40

    「ユーザーのループ」というのは,私が提案したコードだと,Customer モデルの thanks_to_all クラスメソッドで実装されています。

    キャンセル

  • 2018/01/06 18:02

    回答ありがとうございます。提案していただいたコードだと def sendmail(user)には
    @user = user
    mail to: name.email, subject: "ありがとうございました。"
    の2行だけでいいのでしょうか?
    cronの記述はrunner "NoticeMailer.sendmail.deliver"ではなくて
    runner "Customer.thanks_to_all.deliver"でいいのでしょうか?
    大量にメールするなら deliver_now じゃなくて云々とありますが、大量にメールすることを想定していますので大量にメールする場合にはどうするのかも教えていただけないでしょうか?
    いろいろしつこくて申し訳ございませんが宜しくお願いいたします。助けてください。

    キャンセル

  • 2018/01/06 18:11

    sendmail メソッドの記述はたぶんそんな感じだと思いますが,まあやってみてください。
    whenever の runner の記述ですが,Customer.thanks_to_all だけで配信までやっちゃうので deliver は付けません。deliver(や deliver_now など)の働きについては rails tutorial とかをもう一度ご覧になってみてください。

    大量メールについては私は答えられません。
    一度に大量にメールを配信するとスパム判定されやすくなったり,いろいろ大変です。
    大量メールについては,Rails でどう書くか以前の問題として学ぶべきことがあります。

    キャンセル

  • 2018/01/06 21:20

    回答ありがとうございます。大量メールについては学習してみます。
    もう1つだけ教えてください。
    自分でやろうとしているCustomer.where(gender: 1)が数百人もいた場合のメール送信も
    大量メールの送信になってしまうのでしょうか?

    キャンセル

  • 2018/01/06 22:28

    一概には言えないかと思います。

    キャンセル

  • 2018/01/07 11:56

    いろいろと参考になる回答ありがとうございました。今後とも宜しくお願いします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.23%

関連した質問

同じタグがついた質問を見る

  • Ruby

    5467questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    5366questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。