やりたいこと
rakeタスクを実行する際に、引数を添えて、実行したい。
同時に、findやwhereなどで条件は同じで、モデル名がコロコロ変わる変数を用意したい。
つまり、
- rakeタスクに引数を複数添えたい
- rakeタスク内の記述は複数モデルに適用したい
やったこと
まずはrakeタスクの作成
今回は画像の再アップロード用のタスクを作ります。
$ rails g task regenerate_images
生成されたrakeタスクに処理を追加していきます。
追加前(作成直後のrakeタスクファイル)
namespace :regenerate_images do
end
namespaceには生成したrakeタスク名が適用されます。
追加後
namespace :regenerate_images do
desc 'regenerate_images_to_optimize_image_size_and_quality'
task :selected_model, [:table_name, :id, :max_num] => :environment do |task, args|
model_name = args[:table_name].classify.constantize
model_name.find_each(start: args[:id], batch_size: args[:max_num].to_i) do |i|
p "id: #{i.id}"
begin
i.image.cache_stored_file!
i.image.retrieve_from_cache!(item.image.cache_name)
i.image.recreate_versions!
i.save!
rescue => e
Rails.logger.error "ERROR: YourModel: #{i.id} -> #{e.to_s} #{e.backtrace}"
end
end
end
end
desc 'regenerate_images_to_optimize_image_size_and_quality'
の部分はtaskの説明を加える記述で、タスク実行時には入力の必要はありません。
一方で、タスク一覧を表示する以下コマンドを入力した時にタスク一覧のなかで、desc内の記述が表示されます。
$ rake -T
実行結果
rake regenerate_images:selected_model[table_name,id,max_num] # regenerate_item_images
rakeタスクの実行
rakeタスクの実行は$ rake namespace:task名
で可能です。
また、引数を指定したい場合は、配列に渡して、実行できます。
実際に先程お見せしたスクリプトを実行してみると、
例えば
$ rake regenerate_images:selected_model[products,100,500]
のような呼び出し方になります。
rakeタスクの引数を複数個指定する
rakeタスクの引数を複数にしたかったので以下の記事を参考にしました。
↓
Rake タスクの作り方(引数を複数設定してみる)https://qiita.com/yoshiokaCB/items/c97ba878469701c3d99b
args[:hoge]で引数として渡した値を指定できます。
※args.hogeでも可
model_nameには、args[:table_name]を代入しているので、"products"が代入されることになります。
次に、モデル名.find_eachを実現したかったので、変数のmodel_nameに入るStringクラスの文字列がClassクラスになるようにclassify
とconstantize
メソッドを用いました。
今回のまとめ
- rakeタスクの生成と呼び出し
- 複数引数の指定