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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

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

Ruby on Rails

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

Q&A

解決済

1回答

802閲覧

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

koume

総合スコア458

Ruby

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

Ruby on Rails

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

0グッド

1クリップ

投稿2018/01/05 11:36

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フォルダに
メーラーを記述するのでしょうか?

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

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

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

つまり,

rb

1class NoticeMailer 2 # 中略 3 4 def sendmail(user) 5 # 略 6 end 7end

と。

なお,

rb

1@user = Customer.where(gender: 1)

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

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

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

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

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

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

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

rb

1class Customer < ApplicationRecord 2 # 略 3 4 def self.thanks_to_all 5 where(gender: 1).each do |user| 6 NoticeMailer.sendmail(user).deliver_now 7 end 8 end 9end

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

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

rb

1Customer.thanks_to_all

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

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

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

投稿2018/01/06 05:15

scivola

総合スコア2108

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koume

2018/01/06 08:31

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

2018/01/06 08:40

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

2018/01/06 09: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 じゃなくて云々とありますが、大量にメールすることを想定していますので大量にメールする場合にはどうするのかも教えていただけないでしょうか? いろいろしつこくて申し訳ございませんが宜しくお願いいたします。助けてください。
scivola

2018/01/06 09:11

sendmail メソッドの記述はたぶんそんな感じだと思いますが,まあやってみてください。 whenever の runner の記述ですが,Customer.thanks_to_all だけで配信までやっちゃうので deliver は付けません。deliver(や deliver_now など)の働きについては rails tutorial とかをもう一度ご覧になってみてください。 大量メールについては私は答えられません。 一度に大量にメールを配信するとスパム判定されやすくなったり,いろいろ大変です。 大量メールについては,Rails でどう書くか以前の問題として学ぶべきことがあります。
koume

2018/01/06 12:20

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

2018/01/06 13:28

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

2018/01/07 02:56

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問