はじめに
月1回バッチ処理で、テーブルの特定カラムを更新したいと思い、gem「whenever」を使用して、バッチ処理を実装しようとしたものの、Herokuでは使用できなかったため、Heroku Schedulerを使用して、月一回のバッチ処理を実装しました。実装するにあたり、情報が少なかったため、同様の悩みをお持ちの方のお役に立てばと思い、記載いたします。
開発環境
- Mac
- Ruby 2.7.2
- Rails 6.1.3.1
- PostgreSQL 13.2
タスクの定義
Schedulerで実行したいタスクを定義します。rails g task タスク名
コマンドでタスクを定義します。今回はタスク名を「reset_eat_day_month」としました。
rails g task reset_eat_day_month
成功すると、lib/tasks
下にタスクが作成されます。私の場合、usersテーブルのeat_day_monthというカラムを0に更新したかったため、以下のタスクを定義致しました。
# 名前空間
namespace :reset_eat_day_month do
# タスクの説明
desc "usersテーブルのeat_day_monthをリセットする"
# タスクの名前
task reset_eat_day: :environment do
begin
user = User.all
user.update(eat_day_month: 0)
puts "リセット完了"
rescue StandardError => e
# 例外が発生した場合の処理
# リセットできなかった場合の例外処理
puts "#{e.class}: #{e.message}"
puts "-------------------------"
puts e.backtrace # 例外が発生した位置情報
puts "-------------------------"
puts "リセットに失敗"
end
end
end
定義したタスクがきちんと表示されるか確認。
bundle exec rake -T
以下のように定義したタスクが出力されていることを確認。
rake reset_eat_day_month:reset_eat_day # usersテーブルのeat_day_monthをリセットする
タスクが定義されていることを確認後、以下のコマンドを実行して、タスクが想定通り動くかを確認。
bundle exec rake reset_eat_day_month:reset_eat_day
想定通りにusersテーブルのeat_day_monthというカラムが0になっていることをPosticoにてSQLを発行して確認。
Herokuのアドオンをインストールする
Heroku Schedulerを使うためには、スケジューラのアドオンをインストールする必要があります。以下コマンドで、アドオンをインストールします。
heroku addons:add scheduler:standard
スケジューラを設定する
定義したタスクをスケジューラに登録します。以下コマンドで、Heroku Scheduler画面を開きます。
heroku addons:open scheduler
以下の画面で「Add job」ボタンを押す。
以下の画面のように「Every day at...」を選択して、毎日1回バッチ処理が動くようにします。
今回は月初に1回バッチ処理を動かしたいのですが、デフォルトの選択肢には、毎日1回か1時間に1回、10分ごとに1回しかないです。
そのため、毎日1回バッチ処理を動かし、Run Commandの中で、日付が01だったら、タスクを稼働させるというコマンドを入力することで、月初に1回処理が稼働します。
ジョブが稼働する時間はUTC(協定世界時)のため、JST(日本時間)にするにはUTCに+9時間することで、求められます。
以下のように入力が完了したら、「Save Job」ボタンを押す。
以下の画面のように追加したスケジュールが追加されていることを確認します。
まとめ
- Heroku Schedulerのデフォルトスケジュールに月1回がなかったですが、諦めずに他にやり方はないのか?を考えることが大切だと思いました。
- 実装は一気にせずに、少しずつ実装して、実装できたらこまめにプログラムを稼働させて確認することで、想定外のことが起きても原因のスコープが狭いため、原因を特定しやすいと思いました。