使用Paperclip访问S3中保存的文件

时间:2014-01-15 22:12:49

标签: ruby-on-rails amazon-s3 paperclip

我正在使用Rails 4,Ruby 2.0,Paperclip 3.5.2。 我的production.rb有以下

  config.paperclip_defaults = {
  :storage => :s3,
  :s3_credentials => {
  :bucket => ENV['S3_BUCKET_NAME'],
  :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
  :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
  }
  }

我可以保存文件,我可以使用

检索view.html.erb中的文件
  `<%= image_tag card.ai.url(:thumb) %>`

我的问题是,如何在控制器中访问该文件?我想将它添加到zip文件中,z:

def create_zip
....
elsif ENV['RAILS_ENV'] == "production"
        z.add_file(card.ai.path)
...
end

这给出了错误:“无法打开文件:没有这样的文件或目录”。还试过“card.ai.url.path” - 当然没有用。 我读过[Paperclip + S3大规模压缩,但不,我不想禁用任何东西。所以基本上有很多帖子说明如何在.html.erb文件中显示图像文件,但我想在控制器中访问它。

- 接近完成

已经到目前为止......它不会使网站崩溃,而temp_file会进入zip文件,但temp_file为空。

        s3One = AWS::S3.new(:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
                         :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
        cardsets_bucket = s3One.buckets[ENV['S3_BUCKET_NAME']]
        ai_file_object = cardsets_bucket.objects[card.ai]

        temp_dir_name = "#{Rails.root}/public/temp/pictures}"
        temp_dir = File.dirname("#{temp_dir_name}")
        unless File.directory?("#{temp_dir_name}")
          FileUtils.mkdir_p("#{temp_dir_name}")
        end
        if File.exists?("#{temp_dir_name}/tempPicture.jpg")
          File.delete("#{temp_dir_name}/tempPicture.jpg")
        end
        temp_file = File.new("#{temp_dir_name}/tempPicture.jpg", 'w')

        File.open("#{temp_dir_name}/tempPicture.jpg", 'w') do |file|
          ai_file_object.read do |chunk|
          file.write(chunk)
          end
        end
        z.add_file("#{temp_dir_name}/tempPicture.jpg")

还试过ai_file_object = cardsets_bucket.objects [card.ai.url] - 还是tempPicture为空。还尝试了card.ai.path并导致错误AWS无法找到密钥。

提前致谢。

2 个答案:

答案 0 :(得分:2)

我需要找出S3中的文件路径,并在下载时使用“wb”。我查看了我的开发public / system / cards文件夹,看看paperclip如何命名他们的文件。它是TABLENAME / ATTACHED_FILE / 000/000 / CARD.ID / original。 (注意tablename和attached_file是复数,'original'可以用'thumb'代替。) 我也把它放到一个视图&lt;%= card.ai.path%&gt;中,它给了我路径

  

/cards/ais/000/000/001/original/startransparentbrownsmall.jpg

我的模型看起来像这样:

  class Card < ActiveRecord::Base
  belongs_to :cardset
  ...    
  has_attached_file :ai, styles: {
    thumb: '50x50>',
    square: '100x100>',
    medium: '200x200>'
  }
end

以下是有效的代码:

        s3_file_path ="cards/ais/000/000/#{format("%03d", card.id)}/original/#{card.ai_file_name}"
        temp_dir_name = "#{Rails.root}/public/temp/pictures/cards/ais/000/000/#{format("%03d", card.id)}/original"

        temp_dir = File.dirname("#{temp_dir_name}")
        unless File.directory?("#{temp_dir_name}")
          FileUtils.mkdir_p("#{temp_dir_name}")
        end

        if File.exists?("#{temp_dir_name}/#{card.ai_file_name}")
          File.delete("#{temp_dir_name}/#{card.ai_file_name}")
        end

        s3 = AWS::S3.new(:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
                         :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
        bucket = s3.buckets[ENV['S3_BUCKET_NAME']]

        File.open("#{temp_dir_name}/#{card.ai_file_name}", "wb") do |f|
          f.write(bucket.objects["#{s3_file_path}"].read)
        end
        z.add_file("#{temp_dir_name}/#{card.ai_file_name}")

以下是帮助我的网站:

http://docs.aws.amazon.com/AWSImportExport/latest/DG/ManipulatingS3KeyNames.html

1Is there a way to download a file from s3 using the ruby gem aws-s3? Nicolas Blanco回答2

答案 1 :(得分:0)

我认为您希望url不是path

card.ai.path # => /bucket/model/id/file
card.ai.url  # => https://s3.amazonaws.com/bucket/model/id/file

您可以进入rails控制台并检查这些值以确保

z.add_file(card.ai.url)
# or maybe
z.add_file(open(card.ai.url))

您也可以像这样检查您的环境 - 而不是直接检查ENV

elsif Rails.env.production?
  # ...