为回形针附件创建sha1路径

时间:2013-07-08 00:31:12

标签: ruby-on-rails paperclip

我正在尝试为我的附件创建一个看起来像这样的路径。

/4a6/341/f95/345b2b7a5f25b9c87da28feff52e549.pdf

这是我到目前为止的代码。

# config/initializers/paperclip.rb
Paperclip.interpolates :hash_path do |attachment, style|
  hash_path = ""
  token = attachment.instance.token
  3.times { hash_path += token.slice!(0..2) + "/" }
  hash_path + token
end

# app/models/report.rb
class Report < ActiveRecord::Base
  include Paperclip::Glue
  has_attached_file :attachment, url: "/reports/:hash_path.:extension", use_timestamp: false
  validates_attachment_content_type :attachment, content_type: ["application/pdf"]
  validates_uniqueness_of :token

  def create_token
    self.token ||= Digest::SHA1.hexdigest([
      Time.now.to_f.to_s,
      rand(10**5).to_s
    ].join)
  end
end

当我尝试创建报告时,我收到以下错误。

Errno::ENOENT: No such file or directory - /Users/linus/Documents/Projekt/public/reports/9b5/10f/92d/ea7215026a94db6b088b19.pdf
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/storage/filesystem.rb:39:in `initialize'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/storage/filesystem.rb:39:in `open'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/storage/filesystem.rb:39:in `block in flush_writes'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/storage/filesystem.rb:37:in `each'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/storage/filesystem.rb:37:in `flush_writes'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/attachment.rb:214:in `save'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/instance_methods.rb:17:in `block in save_attached_files'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/instance_methods.rb:10:in `block in each_attachment'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/instance_methods.rb:9:in `each'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/instance_methods.rb:9:in `each_attachment'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/paperclip-3.4.1/lib/paperclip/instance_methods.rb:16:in `save_attached_files'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:416:in `_run__3108444119656637369__save__1047547937905355348__callbacks'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `__run_callback'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:385:in `_run_save_callbacks'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81:in `run_callbacks'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/callbacks.rb:264:in `create_or_update'
... 23 levels...
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in `save!'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/attribute_methods/dirty.rb:33:in `save!'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in `block in save!'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/transactions.rb:208:in `transaction'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/transactions.rb:264:in `save!'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/validations.rb:41:in `create!'
  from /Users/linus/Documents/Projekt/app/models/gig_subscription.rb:104:in `create_reports!'
  from (irb):1
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
  from /Users/linus/.rvm/gems/ruby-2.0.0-p0/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `<main>'2.0.0p0 :002 > exit

我正在使用带有rails 3.4.1和Ruby 3.2.13的paperclip版本2.0.0。 我做错了什么?

1 个答案:

答案 0 :(得分:0)

我实际上有两个问题必须解决才能帮助我实现目标。

1。)我没有意识到这一点,但看起来token = attachment.instance.token只返回指向Report#token的指针。如果我然后将String#slice!应用于token,那么它自己的对象将会被更改,即全局。解决方案是在应用attachment.instance.token之前创建String#slice!的重复版本,就像这样。

# config/initializers/paperclip.rb
Paperclip.interpolates :hash_tag do |attachment, style|
  hash_path = ""
  token = attachment.instance.token.dup
  3.times { hash_path += token.slice!(0..2) + "/" }
  hash_path + token
end

2。)第二个问题是:hash_tag是回形针中的保留字。把它改成别的东西解决了这个问题,就像这样。

# config/initializers/paperclip.rb
Paperclip.interpolates :tag do |attachment, style|
  hash_path = ""
  token = attachment.instance.token.dup
  3.times { hash_path += token.slice!(0..2) + "/" }
  hash_path + token
end

# app/models/report.rb
class Report < ActiveRecord::Base
  include Paperclip::Glue
  has_attached_file :attachment, url: "/reports/:tag.:extension", use_timestamp: false
  validates_attachment_content_type :attachment, content_type: ["application/pdf"]
  validates_uniqueness_of :token

  def create_token
    self.token ||= Digest::SHA1.hexdigest([
      Time.now.to_f.to_s,
      rand(10**5).to_s
    ].join)
  end
end