Rails でオブジェクトを作成するときに、ユーザーが後で上書きできるように、assets ディレクトリからストック イメージを自動的に割り当てたいと考えています。
その結果、オブジェクトの作成時に次のプライベート メソッドを実行します。
def save_stock_image
image_path = Dir.glob(<list-of-images-from-directory>).sample
File.open(image_path) do |file|
self.image = file
self.save!
end
end
ただし、6 回の RSpec テストの後、次のエラーが発生し始めます。
Failure/Error: let(:object) { create(:object) }
Errno::EMFILE:
Too many open files - /tmp/16020130822-36578-q8j9v9.jpg
# ./app/models/object.rb:502:in `block in save_stock_image'
# ./app/models/object.rb:501:in `open'
# ./app/models/object.rb:501:in `save_stock_image'
# ./spec/controllers/object_controller_spec.rb:318:in `block (3 levels) in <top (required)>'
# ./spec/controllers/object_controller_spec.rb:344:in `block (4 levels) in <top (required)>'
上記のエラーは、60 回のテストのうち 40 回まで発生します。私はいくつかのSOの質問と、https://github.com/thoughtbot/paperclip/issues/1122およびhttps://github.com/thoughtbot/paperclip/issues/1000を見てきました。私が見つけた最も近い答えは、ファイル記述子が閉じていることを確認することでした。File.open
ブロックで使用する前に、ファイルを明示的に閉じましたfile.close
-これも機能しませんでした。
私が間違っていることは明らかですか?私がやろうとしていることを達成するためのより良い方法はありますか?
アップデート
S3 にアップロードされる前に Paperclip が作成する一時ファイルと関係があるようです。欠落している一時ファイルを閉じると何かありますか?