Carrierwave上传命中Errno :: EEXIST - 文件存在错误

时间:2014-10-20 09:07:55

标签: carrierwave osx-snow-leopard capistrano3

在两台机器上安装了rails3.2.18应用程序:Ubuntu 14.04和osx 10.6用于测试目的。

在OS X框上提交要上传的文件(这些文件有意大),载波返回Errno::EEXIST in [...] controller指定:

File exists - /Users/user/app/releases/20141018152115/public/uploads

Ubuntu安装时没有发生此错误。存在public/uploads,因为它需要是shared/public/uploads的符号链接,以满足持久性要求。 capistrano3部署命令

set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}

设置符号链接。为了更好的衡量,我按顺序在两台机器上运行部署以隔离任何应用程序问题。

所以这似乎又是一个OSX问题。一个假设是给定的阶段文件以某种方式错误配置为OSX,尽管具有管理员权限的(唯一)用户被适当地指定:

set :deploy_to, '/Users/osxuser/app'
set :use_sudo, false
set :deploy_user, 'osxuser'

另一个假设与从Capistrano2迁移到Capistrano3有关,因为这个osX服务器在升级之前没有这样的问题。

'文件如何存在'错误被消除了?

更新

/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:244:in `mkdir'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:244:in `fu_mkdir'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:221:in `block (2 levels) in mkdir_p'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:219:in `reverse_each'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:219:in `block in mkdir_p'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:205:in `each'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:205:in `mkdir_p'
carrierwave (0.9.0) lib/carrierwave/sanitized_file.rb:290:in `mkdir!'
carrierwave (0.9.0) lib/carrierwave/sanitized_file.rb:209:in `copy_to'
carrierwave (0.9.0) lib/carrierwave/uploader/cache.rb:131:in `block in cache!'
carrierwave (0.9.0) lib/carrierwave/uploader/callbacks.rb:17:in `with_callbacks'
carrierwave (0.9.0) lib/carrierwave/uploader/cache.rb:122:in `cache!'
carrierwave (0.9.0) lib/carrierwave/mount.rb:327:in `cache'
carrierwave (0.9.0) lib/carrierwave/mount.rb:179:in `production_file='
carrierwave (0.9.0) lib/carrierwave/orm/activerecord.rb:38:in `production_file='
activerecord (3.2.18) lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
activerecord (3.2.18) lib/active_record/attribute_assignment.rb:78:in `each'
activerecord (3.2.18) lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
activerecord (3.2.18) lib/active_record/persistence.rb:216:in `block in update_attributes'
activerecord (3.2.18) lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
activerecord (3.2.18) lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
activerecord (3.2.18) lib/active_record/transactions.rb:208:in `transaction'
activerecord (3.2.18) lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
activerecord (3.2.18) lib/active_record/persistence.rb:215:in `update_attributes'
app/controllers/bozzadocuments_controller.rb:62:in `block in update'

堆栈跟踪似乎想要mkdir carrierwave (0.9.0) lib/carrierwave/sanitized_file.rb:290:in mkdir!

载波上传器的指定如下

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.quote.cart_id}_#{model.quote.cart.created_at}_/#{model.quote_id}/#{model.id}"
  end

1 个答案:

答案 0 :(得分:2)

This is a pitfall when creating an OS-X 'alias' instead of a symlink.

(Not in the actual gems resp. any specific version – I experienced the same today with rails 5.0.0.1, ruby 3.2.1 and carrierwave 0.11.2.)

It turned out that I had accidently created not a symlink but an alias using the OS X Finder (which technically is not a symlink). When carrierwave then tries to create the folder structure FileUtils.mkir_p raises an error on trying to (re)create the (existing) alias as a directory.

rm ./app/releases/20141018152115/public/uploads ln -s ./app/shared/public/uploads ./app/releases/$timestamp/public/uploads

should do the trick.

[EDIT: Clarified the actual root cause is not in ruby, rails or the gems in use]