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

3

我正在使用 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 massive zipping,但我不想禁用任何东西。所以基本上有很多帖子说如何在 .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个回答

2

我需要找出S3中的文件路径,并在下载时使用“wb”。 我查看了我的开发public/system/cards文件夹以查看paperclip如何命名它们的文件。它是TABLENAME / ATTACHED_FILE / 000/000/CARD.ID/original。(注意,tablename和attached_file是复数,'original'可以替换为'thumb')。

我还将此放入视图<%= card.ai.path %>,这给了我路径

/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

1: 有没有一种使用Ruby宝石aws-s3从S3下载文件的方法? Nicolas Blanco的第二个回答


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?
  # ...

z.add_file(card.ai.url) 和 open(card.ai.url) 都不起作用。它们对你有用吗?我一直在研究,似乎我必须使用正确的 S3::Bucket 向 aws S3 请求文件。 - flobacca
查看 card.ai.url 返回的内容,并将其粘贴到浏览器中。 - house9
http://s3.amazonaws.com/bucketname/pathtofile 这个链接在浏览器中显示访问被拒绝,我需要一种方法来告诉浏览器我的公钥和私钥。我已经在我的Rails应用程序中提供了密钥,但我不确定如何使用Ruby语法获取文件。 - flobacca
card.ai.expiring_url(600) 会生成一个签名链接,该链接有效期为5分钟。 - house9
我不是在寻找链接,我需要压缩文件。我不太确定你的计划是什么。 - flobacca
一旦您有一个可以在浏览器中打开的URL,那么您应该能够使用它将文件添加到您的zip文件中。 - house9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接