LoginSignup
28
25

More than 5 years have passed since last update.

[初学者]whenever を使って定期的にバッチ処理を行う(公開設定編)

Last updated at Posted at 2018-06-28

目的

  • 自分用のメモです
  • 条件
    • WordPressみたいなブログサイト
    • 記事のステータスは、「下書き」「公開待ち」「公開」の3種類
    • 記事を保存時に上記ステータスと公開日(日付)の設定が必須
    • 「公開待ち」の記事で期限到来日(公開日)によりステータスを自動で「公開」に変更

動作環境

  • ruby 2.5.0
  • Rails 5.2.0
  • mysql Ver 14.14 Distrib 5.7.22

手順リスト

  1. 「rails g task」コマンドでタスク(処理)を作成
  2.  gem 'whenever'を導入し、タスクを定期的にバッチ処理

1. 「rails g task」コマンドでタスク(処理)を作成

タスクファイルを生成
rails g task check_date
# lib/tasks/check_date.rakeにファイルが生成される
app/models/article.rb
# enumの設定です [下書き 公開待ち 公開]
enum state: %i[draft wait_publish published]
lib/tasks/check_date.rake
namespace :check_date do 
  desc "check_state" # このタスクの説明を書く
# タスクの名前。 「:environment」がないとDBやモデルにアクセスできないので、使う場合は付ける
  task check_state: :environment do 
    Article.where('published_at <= ?', Time.zone.now).wait_publish.each(&:published!)
# articlesテーブルで[公開日が現在時刻以前かつステータス「公開待ち」]のものを全て「公開」に変更
  end
end

処理が本当に走るのか確認する

タスクの一覧を表示
rails -T

qiita_task.jpg

ここで、タスク処理の設定は完了です。
次は、設定したタスクを定期的にバッチ処理を行うよう設定していきます。

2. gem 'whenever'を導入し、タスクを定期的にバッチ処理

Gemfile

# crontab管理
gem 'whenever', require: false

# 上記を記載後、bundle install
設定ファイルを作成
bundle exec wheneverize .

> [add] writing './config/schedule.rb' #<= 設定ファイルが生成
> [done] wheneverized! #<= 成功
config/schedule.rb
# Rails.rootを使用するために必要。なぜなら、wheneverは読み込まれるときにrailsを起動する必要がある
require File.expand_path(File.dirname(__FILE__) + "/environment")
# cronを実行する環境変数
rails_env = ENV['RAILS_ENV'] || :development
# cronを実行する環境変数をセット
set :environment, rails_env

# cronのログの吐き出し場所。ここでエラー内容を確認する
set :output, "#{Rails.root}/log/cron.log"

# 3時間ごとに[lib/tasks/check_date.rake]を実行する
every 3.hours do
  rake 'check_date:check_state'
end

# [課題]
# メモ:厳密に言うとこのコードにはバグが含まれていると思っていて、3時間おきにタスク実行させているので!
# 例えば12:00にタスクが走った後、公開時刻が12:01の記事があった場合でも、次にタスクが走るのは15:00、つまり15:00にならないと公開状態にならないようなコードとなっています。
# 既存のものに修正を加えるとなると、色々とデータの整合性を保たなければいけなくなるので、
# その辺今後意識していきましょう。
# [試したこと]
# コールバックを設定したけど、それだとSQLを走らせる回数が増えるのでよくない。

Corntabへの設定


# 設定内容にエラーがないか確認
bundle exec whenever

# 設定されているcronを見る
crontab -l

# wheneverの設定更新
RAILS_ENV=development bundle exec whenever --update-crontab

# crontabの設定削除
RAILS_ENV=development bundle exec whenever --clear-crontab

気づき

config/application.rb
config.autoload_paths += %W(#{config.root}/lib)

あまり考えずに設定してたけど、Rails5のproduction環境では不具合がでるので注意しとく。

Rails5のproduction環境でlib/配下のクラス読込みがNameErrorになるのはautoloadが無効化されたからだった

Rails5: production環境でのAutoloadの廃止

参考

28
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
25