LoginSignup
9
5

More than 1 year has passed since last update.

Railsのタスクを定義する

Posted at

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
9
5
1

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
9
5