Ruby on Railsアプリケーションを開発で定型の操作を繰り返すときは、タスクを定義すると便利です。
前提条件
あるRailsアプリケーションでは、ファイルアップロードジョブの途中で例外がおきたとき、処理途中のファイルやレコードが残ります。このため、開発の途中でしばしば次のコマンドを実行して、ゴミ掃除をしています。
bin/rails runner 'Job.destroy_all'
rm -rf tmp/upload-*
テンプレートの作成
今回はこのコマンドをRailsのタスクにしてみたいと思います。
Railsのタスクの実体はlibディレクトリ配下にあるRakeタスクです。
テンプレートをRailsのジェネレートコマンドで作ることが出来ます。
まず、最初にどのようなコマンドで、実行できると良いか考えてみましょう。
ジョブのゴミ掃除なので、job:clean
が良いと思います。
完成したら次のように実行するイメージです。
bin/rails job:clean
タスク名がきまったらジェネレートコマンドでテンプレートを作成します。
bin/rails g task job clean
:で区切られたタスク名を空白で区切って指定します。
するとlibディレクトリに次のようなテンプレートが作成されます。
namespace :job do
desc "TODO"
task clean: :environment do
end
end
このtaskブロックに必要な処理を記述します。
レコードの削除
まず、簡単なJob.destroy_all
を書いてみます。
namespace :job do
desc "TODO"
task clean: :environment do
Job.destroy_all
end
end
これだけでレコードを削除するRailsのタスクが定義できました。
ファイルの削除
次にファイルの削除も対応してみましょう。
rm -rf tmp/upload-*
をRubyスクリプトに置き換えます。
rm -rf
の代わりにFileUtils.rm_rf
を使います。
メソッドに指定するディレクトリのパスを取得します。
tmpディレクトリは実際にはRailsアプリケーションのtmpディレクトリです。
つぎのように、該当するディレクトリを取得します。
Dir.glob Rails.root.join("tmp/upload-*")
これをタスクファイルに追加します。
namespace :job do
desc "TODO"
task clean: :environment do
Job.destroy_all
require 'fileutils'
FileUtils.rm_rf(Dir.glob Rails.root.join("tmp/upload-*"))
end
end
完成
bin/rails job:clean
を実行して、期待通りにゴミ掃除できているか確認します。
できていたら整形します。
namespace :job do
desc "Delete the remnants generated by the annotation upload job"
task clean: :environment do
# Delete Job records
Job.destroy_all
# Delete uploaded files
require 'fileutils'
directory = "tmp/upload-*"
list = Dir.glob Rails.root.join(directory)
FileUtils.rm_rf(list)
end
end