Ryota400’s blog

エンジニアを目指して書いてます。

whenever による記事数一覧のメール送信

実装したいこと

・wheneverを導入して毎日am9:00に下記の内容を管理者にメールで送信させるメールの件名には「公開済記事の集計結果」と設定

・管理者のメールアドレスにはadmin@example.comを設定

Image from Gyazo

Mailer作成

記事数一覧メールを送信できるように「送信するためのメソッド」と「メール本体」を作成

rails g mailer ArticleMailer

・ActiveMailer::Baseを継承したApplicationMailerとArticleMailer(自分で命名したもの)が生成される。

・Mailerを作成するとviewのディレクトリとテストも同時に作成される。

app/mailer/application_mailer.rb

class ApplicationMailer < ActionMailer::Base

  default from: 'from@example.com'

  layout 'mailer'

end

mailerのviewでHTMLタグなどを書かないこと
他のViewファイル同様レイアウトファイルが指定されているから 書いてしまうと重複になってしまう。

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: 'admin@example.com', subject: '公開済記事の集計結果')
  end
end

・@publish_article_countは全ての記事の中で公開されている記事の数を出しているもの
・@article_publish_at_yesterdayは全ての記事の中で公開日が昨日のものを表示している。
・admin@example.comに送る設定で、題名は「公開済記事の集計結果」
・Article.published_at_yesterdayのpublished_at_yesterdayの部分はscopeを使い指定してやる必要がある(そうじゃないと使えない)

article.rb

 scope :published_at_yesterday, -> { where(published_at: 1.day.ago.all_day) }

@publish_article_count=公開記事の総数と@article_publish_at_yesterday=昨日記事を公開した記事の情報をメールに表示することができるようになる。

メールを書く
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| %>
    タイトル: <%= article.title  %>
    公開日時: <%= l(article.published_at) %>
  <% end %>
<% else %>
  昨日公開された記事はありません
<% end %>

wheneverを使って毎朝9時に「記事数一覧メールを送信する」というメソッドを実行
config/schedule.rb

every 1.day, at: '9am' do
  rake 'article_summary:mail_article_summary'
end
 bundle exec whenever --update-crontab 

最後に変更をcronに反映させる

メール送信の定期実行

lib/tasks以下にcronを使用して、定期的に実行する処理のかたまり(rakeタスク)を作成していく lib/tasks/article_summary.rake

namespace :article_summary do
  desc '管理者に対して総記事数、昨日公開された記事数とタイトルをメールで送信'
  task mail_article_summary: :environment do
    ArticleMailer.report_summary.deliver_now
  end
end

・namespaceはfile名と揃える(自分で作成)
・"desc"はこのタスクの説明(自分で作成)
・"task" の "mail_article_summary:" は自分で命名していい。config/suchedule.rbにも同じ名前を記述することになる。

letter_opener gem

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

環境設定
Gemfileにletter_opener_webを追加

group :development do
  gem 'letter_opener_web'
end

config/environments/development.rb

  config.action_mailer.delivery_method = :letter_opener_web
  config.action_mailer.default_url_options = { host: 'localhost:3000' }

route.rb

if Rails.env.development? #開発時用の処理
  get '/login_as/:user_id', to: 'development/sessions#login_as' #開発環境でログインする為
  mount LetterOpenerWeb::Engine, at: '/letter_opener' #今回ここ追加
end

これで、http://localhost:3000/letter_opener/で確認することが可能

参考文献

wheneverを使って定期的にメールを送信する方法 - Qiita

【Rails】開発中に送ったメールを確認する(Gem: letter_opener) - おぴよの気まぐれ日記

GitHub - javan/whenever: Cron jobs in Ruby

Rails メール自動配信機能をActionMailerとwheneverを使用して実装する - Qiita