rake task, cron,whenever ①(rake task作成)
rake task, cron,wheneverの使い方を学んでいく。
rake taskを作成するときに必要なメソッド
rake task作成
$ rails g task hoge
success create lib/tasks/hoge.rake
作成されたファイルを編集する上で知っておきたいrakeタスクの書き方↓
namespace :hoge do
# タスクの説明 desc => description(説明)
desc ""
# task_name => タスクの名前
task task_name: :environment do
# 実行したい処理を記述する場所
end
end
実際に編集していく。今回は、調子を確認してくれるrake taskを作成する
namespace :hoge do
# タスクの説明 desc => description(説明)
desc "調子を確認してくれる"
# howya_doin => タスクの名前
task howya_doin: :environment do
# 実行したい処理を記述する場所
puts "How are you ?"
end
end
これでrake taskが完成したので、作成されたかを確認する
$ rake -T
色々ズラーっとタスクが並んでいる中に、下記コードが追加されていたら作成に成功している。
rake hoge:howya_doin # How are you ?を表示するタスク
タスクを実行してみる。
rake hoge:howya_doin
以下のような表示になれば成功。
How are you ?
cron
時間ごとにタスクが実行されるようにしてくれる優れもの
例えば、「XXというコマンドをXX時に実行する」というタスクを設定することができる。
whenever
ruby gemのうちの一つで、cronを使いやすくしてくれる優れもの。
wheneverをインストールした際に生成されるschedule.rbに、bundle exec whenever --update-crontab
といったコマンドを記述することで、定期的にcronを実行してくれる。
rake taskの書き方応用
今回は、「もし下書きの投稿時間が現在時刻より過去のステータスだったら、ステータスを公開にかえる」というタスクにする。
(1)まず、「下書き状態の投稿」 を定義する。
Article.wait_publish
(2) 次に、(1)より前の投稿を探すメソッドを作る。(1)より前の投稿ということは、publish_atがTime.currentより前の投稿を探すことを意味しているので、コードに直すと下記の通りになる。
'published_at <?', Time.current
scopeを使ってモデルに定義すると、以下の通りになる。モデルに定義したスコープは別のコントローラで呼び出すことができるので、Fat Controller問題の解消に非常に役立つ方法。
scope :viewable, -> { published.where('published_at < ?', Time.current) }
さっき定義した「下書き状態の投稿」とこのscopeを組み合わせることで、「下書きの投稿時間が現在時刻より過去のステータス」の投稿を定義することができる。
Article.wait_publish.viewable
そして、最後にpublishを付け加えることで、
「下書きの投稿時間が現在時刻より過去のステータス」を「投稿する」(投稿というステータスに変える)
を実装することができる。
Article.wait_publish.viewable.publish
しかしこれだけだと、投稿数がひとつになってしまい、複数の現在時刻より過去の下書きを投稿することができない。
複数の項目を探して、それぞれの項目に対してメソッドを適用させたいときは、find_eachを使うと良い。
そして、探し出した項目それぞれを投稿状態に変えるために、&:published!を付け加える。
(3)
find_each(&: published!)
(1), (2), (3) をつなげることで、
「もし下書きの投稿時間が現在時刻より過去のステータスだったら、ステータスを公開にかえる」というタスクを作成することができる。
Article.publish_wait.viewable.find_each(&:publish!)
そして 上記メソッドをlib/tasks/article_state.rakeに記載することで、rake taskを実行することができる。
$ rails g task article_state
success create lib/tasks/article_state.rake
lib/tasks/article_state.rake
namespace :article_state do
desc 'もし下書きの投稿時間が現在時刻より過去のステータスだったら、ステータスを公開にかえる'
task change_publish: :environment do
Article.publish_wait.viewable.find_each(&:publish!)
end
end
これで、rake taskをターミナル上で実行することができるようになった。
$ rake article_state:hange_publish
//Article.publish_wait.viewable.find_each(&:publish!)が実行される。