Rakeタスク
まずRakeとは、rubyで処理内容を定義できるビルドツールです。 そしてこのRakeが実行する処理内容を「Rakeタスク」と呼び、定義する場所を「Rakefile」と呼びます。 whenneverと組み合わせることにより、自由なタイミングで処理を走らせることができます。
タスク
タスクとは、テストの実行やデータベースの更新などのタスクを実行してくれます。Rakeなしでこのような小さなタスクを実行しようと思うと、違うファイルを行き来してしまい、コードが散らかります。
cron
「クロン」または「クーロン」と呼ばれ、「○時になったら○○のコマンドを実行」などといった具合に、定期的にコマンドを実行するためにメモリ場で常に命令を待機しているプロセス(=デーモンプロセス)となります。
ファイル作成
lib/tasks以下ディレクトリにrakeファイルを作ります。
rails g task _article_state
※間違いで_article_stateと入力してしまいました。正しくはarticle_state
rakeタスクに実装していく。
_article_state.rake
namespace :article_state do desc '公開待ちの中で、公開日時が過去のもの:ステータスを「公開」に変更する' task update_article_state: :environment do Article.publish_wait.past_published.find_each(&:published!) end end
task_nameがタスクの名前になります。どういう処理を行うタスクなのか分かりやすい名前をつけてあげると、後々タスクが増えた時にも混乱しなくて済みます。 DBとのやり取りがある処理の場合「:environment」を記載する必要がある。 Articleから「公開待ち」の状態で公開日時が現在〜過去のものを取ってきてから、find_eachでループさせます。 必要なデータだけ先に抽出してから繰り返し処理をしています。 (&:メソッド名)でpublished!を実行しています。 Rubyチェリー本P98に詳細の説明あり。
公開日時が現在〜過去の記事を取得するscopeを準備
article.rb
scope :past_published, -> { published.where('published_at <= ?', Time.current) }
Rakeタスクの実行
Rakeタスクの一覧を表示して登録されているか確認します。
以下のコマンドを入力することで、Rakeタスクの一覧を表示してくれます。以下は同じ出力結果になります。
bundle exec rake --tasks
bundle exec rake -T
bundle exec rake _article_status:manage_status
Wheneverの導入
Wheneverはcron jobを実行してくれます。つまり、cronをruby文法で実行してくれるライブラリーです。 本来は「○○時になったら○○を実行」するcronというプロセスを自前で用意する必要があるのですが、wheneverを使えばcronに対して命令を行うcrontabに記述する内容をruby言語で書けるようになります。 これによりRakeタスクを1時間ごとに走らせるように設定することが可能です。
gem 'whenever', require: false
% bundle exec wheneverize .
schedule.rbファイル内にcron処理の設定を書き込む。 schedule.rb
# Rails.rootを使用するために必要 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" # 1時間ごとにrakeタスクを実行 every :hour do rake 'article_state:update_article_state' end
公開日時を1時間ごとにしか設定できないようにする。 app/assets/javascripts/admin.js
format: 'YYYY-MM-DD HH:00'
Cronをアップデートする
$ bundle exec whenever --update-crontab
crontab -lで現在設定されているタスクの一覧が表示されます。