対象とする読者
railsを用いたプロダクトでgem 'carrierwave'によって画像をアップロードしている。
aws-cliを用いても画像アップロードが可能だが、Minimagickによるリサイズや圧縮プロセスを踏みたい。
実現したいこと
hoge_uploader.rbに任意のversionを追加した際にS3に再アップロードを行いたい。
rakeタスクで自動化したい。
やったこと
$ rake:regenerate_images[任意のid,任意の数字]
上記コマンドを実行した際に指定のidで処理が始まり、find_eachによる一回あたりの取得件数を指定の件数に絞って再度アップロードし直す。
carrierwaveのWikiを参考にrakeタスクを作成。
regenerate_images.rake
desc 'recreate_and_reprocess_files_stored_on_fog'
task :item, [:id, :max_num] => :environment do |task, args|
ItemImage.find_each(start: args[:id], batch_size: args[:max_num].to_i) do |item|
p "id: #{item.id}"
begin
item.image.cache_stored_file!
item.image.retrieve_from_cache!(item.image.cache_name)
item.image.recreate_versions!
item.save!
rescue => e
Rails.logger.error "ERROR: YourModel: #{item.id} -> #{e.to_s} #{e.backtrace}"
end
end
end
end
配慮した点
- rakeタスクが何らかの影響で落ちた場合、再度id=1から実行するのは面倒だったので、引数に指定出来るように実装した
- find_eachはorderやlimitが無視されるため、startやbatch_sizeといったオプションを使用
不明点
batch_size: args[:max_num].to_i
上記の .to_i
が無いと下記のようなエラーを吐く。
ArgumentError: comparison of Fixnum with String failed
start: args[:id]単体の場合はエラーは発生せず、batch_size: args[:max_num]が記述されている場合はエラーになる。
to_iメソッド加えると大丈夫だった。
参考記事
Rake タスクの作り方(引数を複数設定してみる)
APIdock>method>find_each
[Ruby]Hashにmapで値を変換したHashを作成する