⭐️期待する機能:ActionMailerとWheneverとRakeタスクを使って、毎日am9:00に管理者へメールを送信する機能を実装させたいです。
===========================================================================
ActiveMailerとは?
Railsにはメールを送る仕組みとしてAction Mailer(メイラー)が用意されています。メイラーはコントローラと似ています。
コントローラがテンプレートを通じて画面を出力するように、メイラーはテンプレートを通じてメールを作成、送信することができます。
Rakeタスクとは?
Rakeとは、Rubyで人気のあるタスクランナーです。 タスクとは何か?
Rakeによってタスクへのアクセスを一元化することができます。
Rakeを使用すると、特定のパターンに一致し、最近変更されたファイルを探すことなどが容易になります。
cronとは?
多くのUNIX系OSで標準的に利用される常駐プログラムの一種で、利用者の設定したスケジュールに従って指定されたプログラムを定期的に起動してくれるものです。 このcronに対して命令を行うには、crontabを使います。
enumとは?
enumは列挙型と訳されます。
列挙とは整数が割り当てられた文字を順番に出力していくことを意味します。
enumを使えば、文字の配列に整数を順番に割り当てられます。
なので、他のプログラマーに読みやすいコードを書くことができます。(可読性が上がる)
たとえば、プログラム内にて都道府県に関する情報を扱う場合、01:北海道、02:青森〜47:沖縄という2桁のコードで表現するよりも、
Hokkaido:北海道、Aomori:青森〜Okinawa:沖縄と意味のある単語で表す方がプログラムの可読性が上がります。
また、整数値の範囲が決定されるので誤った数値を使ってしまうことを前もって、防げます。
Railsでは、モデルにenumを定義することで、文字を使ってカラムの値を変更したり、反対に取り出したりできます。
繰り返しになりますが、意味のある単語を使って、操作できるのでプログラマーが開発をしやすくなります。
wheneverとは?
cronをrubyの記法で簡単に扱えるようにしたgemライブラリです。
===========================================================================[導入の流れ]:
メイラーの生成
$bundle exec rails g mailer ArticleMailer
#下記ファイルが生成される!
create **app/mailers/article_mailer.rb #メイラーファイルにメールを送るためのメソッドを追加していく!!**
create app/mailers/application_mailer.rb
invoke slim
create app/views/article_mailer
create app/views/layouts/mailer.text.slim
create app/views/layouts/mailer.html.slim
invoke rspec
create spec/mailers/article_mailer_spec.rb
create spec/mailers/previews/article_mailer_preview.rb
メイラーの編集
生成されたメイラーに、公開済記事についてのメールを送るためのメソッドを追加します。 report_summaryという名前のメソッドにします。
app/mailers/article_mailer.rb
class ArticleMailer < ApplicationMailer
def report_summary
@published_article_count = Article.published.count
@articles_published_at_yesterday = Article.published_at_yesterday
mail(to: '[email protected]', subject: '公開済記事の集計結果')
end
end
[check point!!!!!]
・@published_article_count: 全ての記事の中で公開されている記事の数を出しているものが入る。インスタンス変数にすることでメール本文で使うことができる。
・@articles_published_at_yesterday: は全ての記事の中で公開日が昨日のものが入る。インスタンス変数にすることでメール本文で使うことができる。
・to: '[email protected]': 送信先の指定。
・subject: '公開済記事の集計結果': 題名の指定。
<u>**・published_at_yesterday: 別途scopeで定義する必要あり。**</u>
scopeの作成
app/models/article.rb
# GOOD
scope :published_at_yesterday, -> { where(published_at: 1.day.ago.all_day) }
# NG
scope :published_at_yesterday, -> { where(published_at: Date.yesterday) }
[check point]
・1日全体を表すRangeは Time#all_day で取得します。
メール本文テンプレート作成
メイラーで作成したインスタンス変数を使って、メール本文を作成します。
<aside> 🚫 /article_mailerディレクトリはジェネレートした際に生成されましたが、中身のファイルは別途作成する必要があります。 間違ってもapp/views/layouts/mailer.text.slimなどのレイアウトファイルを削除したり変更してはいけません。
</aside>
app/views/article_mailer/report_summary.text.erb
公開済の記事数: <%= @published_article_count %>件
<% if @articles_published_at_yesterday.present? %> # 昨日公開された記事が存在する場合、
昨日公開された記事数: <%= @articles_published_at_yesterday.count %>件 # 件数を表示
<% @articles_published_at_yesterday.each do |article| %> # each文で回し、
タイトル: <%= article.title %> # タイトルを表示
公開日時: <%= l(article.published_at) %> # 公開日時を表示
<% end %>
<% else %> # 昨日公開された記事が存在しない場合、
昨日公開された記事はありません
<% end %>
<aside> 🚫 HTMLタグなどを書かないよう注意しましょう。 他のViewファイル同様レイアウトファイルが指定されているので、書いてしまうと重複になってしまいます。
</aside>
⚠️下記3
ファイルは、$bundle exec rails g mailer ArticleMailer にてメイラー作成時に追加されているので、削除や変更はしないこと!!!!
app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: '[email protected]' # 送り元のデフォルト値
layout 'mailer'
end
app/views/layouts/mailer.html.slim
html
body
= yield
app/views/layouts/meiler.text.slim
= yield
メイラーのプレビュー機能
ここまで実装したメイラーとビューの動作を、プレビュー機能を使って確認してみましょう。
プレビュー機能は、spec/mailers/previews/article_mailer_preview.rbを使います。
このファイルは前に実行した$bundle exec rails g mailer ArticleMailerコマンドで生成されています。
# Preview all emails at http://localhost:3000/rails/mailers/article_mailer
class ArticleMailerPreview < ActionMailer::Preview
def report_summary
ArticleMailer.report_summary
end
end
Rakeタスク作成
cronを使用して、定期的に実行する処理をRakeタスクの中にまとめたいので、ジェネレートコマンドで生成します。
$ bundle exec rails g task article_summary
create lib/tasks/article_summary.rake
lib/tasks/article_summary.rake
namespace :article_summary do
desc '管理者に対して総記事数、昨日公開された記事があれば記事数とタイトルをメールで送信'
task mail_article_summary: :environment do
ArticleMailer.report_summary.deliver_now
end
end
[check point]
namespace: ファイル名と同じにする
desc: タスクの説明文
task: taskの処理名。自分で命名する。
Wheneverの設定
config/schedule.rb
every 1.day, at: '9am' do
rake 'article_summary:mail_article_summary'
end
└#毎日am9:00に下記の内容を管理者にメールで送信
crontabを実行
crontabを使ってcronに対して命令をします。
$ bundle exec whenever --update-crontab # wheneverの設定更新
$ bundle exec whenever # 設定内容にエラーが無いか確認
$ crontab -l # 設定されているcronを確認
$ bundle exec whenever --clear-crontab # crontabの設定を削除
letter-openerで確認する
ルーティングを設定する
config/routes.rb
if Rails.env.development?
mount LetterOpenerWeb::Engine, at: '/letter_opener'
end
設定ファイル編集
config/environamentes/development.rb
config.adction_mailer.delivery_method = :letter_opener_web
config.action_mailer.default_url_options = { host: 'localhost:3000' }
<aside>
💡 rails sでサーバーを起動し、locaohost:3000/letter_openerにアクセスしてブラウザで確認できます。
</aside>