【问题标题】:Link existing S3 file as paperclip attachment将现有 S3 文件链接为回形针附件
【发布时间】:2014-07-28 18:02:06
【问题描述】:

我有一个创建文件并将它们存储到 S3 的外部服务(我的 Rails 应用程序也可以访问)。

我希望能够使用 Paperclip 来存储该 S3 对象以及它的缩略图。我无法找到有关如何将 Paperclip 与 S3 上已有的文件一起使用的文档。所以,我的代码应该是这样的:

page = Page.find(3)
page.s3_url = s3_url # I have the s3 route. And I would need to generate a thumbnail too.
page.save

所以,换句话说:

如何告诉 PaperClip 我的附件已经在 S3 中?

编辑:

这是我目前所拥有的:

我知道已在 S3 中上传的文件的文件名、内容长度和内容类型。所以,既然关联是一个 Page has_attached_file :screenshot

这就是我的工作:

@page = Page.find(3)
@page.update_attributes(screenshot_content_type: screenshot_content_type, screenshot_file_size: screenshot_file_size, screenshot_update_at: screenshot_updated_at, screenshot_file_name: screenshot_file_name)

所以,现在我可以做:

@page.screenshot 我看到了回形针对象。但是,当我这样做时:

@page.screenshot.url => url 不是我最初存储图像的那个。

【问题讨论】:

    标签: ruby-on-rails paperclip


    【解决方案1】:

    我已经用paperclip interpolations 解决了这个问题:

    1. 在您的模型中定义一个字段,以存储上传文件的路径
    2. 通过属性更新将回形针附件信息加载到数据库
    3. 通过插值指定回形针附件:路径,因此它首先查找上传的文件,然后查找默认文件
    4. 利润!

    这会成功,因为how S3 storage composes urls

    path:这是存储文件的bucket下的key。 URL 将由存储桶和路径构成。这就是您要插入的内容。键应该是唯一的,就像文件名一样,尽管 S3(严格来说)不支持目录,但您仍然可以使用 / 来分隔文件名的各个部分。

    这里有更多的代码细节:

    型号

    class MyModel
        has_attached_file :file, path: ":existent_file_or_default", storage: :s3
    end
    

    回形针插值

    把它放在 config/initializers 下

    Paperclip.interpolates :existent_file_or_default do |attachment, style|
      attachment.instance.existent_file_path ||
        attachment.interpolator.interpolate(":class/:attachment/:id_partition/:style/:filename", attachment, style)
    end
    

    附加现有项目

    MyModel.create({
      existent_file_path: "http://your-aws-region.amazonaws.com/your-bucket/path/to/existent/file.jpeg",
      file_file_name: "some_pretty_file_name.jpeg",
      file_content_type: "image/jpeg",
      file_file_size: 123456
    })
    

    【讨论】:

    • 拯救了这一天:D
    【解决方案2】:

    S3

    Paperclip S3 integration 实际上是相对简单的——你最好看看this Railscast 如何使用 Paperclip,以及前面链接的文档,让你了解 Paperclip 的工作原理;然后你可以将它连接到 S3

    --

    简而言之,Paperclip 基本上采用文件对象并将相关数据保存到您的数据库中。文件的存储取决于您与 Paperclip 关联的服务

    我想说的是这两个元素(数据分配和文件存储)是 gem 的两个不同元素,如果您可以让 Paperclip 处理入站文件,那么您就成功了:


    回形针

    默认实现:

    #app/models/page.rb
    Class Page < ActiveRecord::Base
       has_attached_file :photo
    end
    

    这将允许您将“附件”保存到您的 Page 数据库:

    #app/controllers/pages_controller.rb
    Class PagesController < ApplicationController
       def new
           @page = Page.new
       end
    
       def create
           @page = Page.new(page_params)
       end
    
       private
    
       def page_params
          params.require(:page).permit(:title, :other, :information, :photo)
       end
    end
    
    #app/views/pages/new.html.erb
    <%= form_for @page do |f| %>
       <%= f.file_field :photo %>
       <%= f.submit %>
    <% end %>
    

    这将处理回形针直接上传到您自己的应用程序(将文件存储在public/system 目录中)

    为了让它与 S3 一起工作,您只需将 S3 凭据添加到模型(取自 Paperclip documentation):

    #app/models/page.rb
    Class Page < ActiveRecord::Base
       has_attached_file :photo,
          :storage => :s3,
          :s3_credentials => Proc.new{|a| a.instance.s3_credentials }
    
       def s3_credentials
          {:bucket => "xxx", :access_key_id => "xxx", :secret_access_key => "xxx"}
       end
    end
    

    路径

    如果您想为您的文件调用“S3”文件路径 - 您必须这样做:

    #app/controllers/pages_controller.rb
    Class PagesController < ApplicationController
       def show
          @page = Page.find 3
          @page.photo.url #-> yields S3 path ;)
       end
    end
    

    【讨论】:

    • Rich Peck,实际上我的问题是该文件已经在 S3 中。我不想在 S3 中创建一个新文件,但告诉回形针使用那个文件。
    • 嗯好吧,让我为你修改答案!
    • 我已经尝试设置回形针期望的属性(file_size、updated-at、file_name、content_type),但我没有运气。实际上,我在尝试访问回形针属性时得到以下错误: ArgumentError: missing required :bucket option
    猜你喜欢
    • 1970-01-01
    • 2014-10-20
    • 2013-01-26
    • 1970-01-01
    • 2011-06-29
    • 2014-04-29
    • 1970-01-01
    • 2012-08-13
    • 2016-01-20
    相关资源
    最近更新 更多