将现有S3文件链接为回形针附件

时间:2014-07-28 18:02:06

标签: ruby-on-rails paperclip

我有一个外部服务,可以创建文件并将它们存储到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上传的文件的file_name,content_length和content_type。所以,因为关联是一个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 =>网址不是我最初存储图片的网址。

2 个答案:

答案 0 :(得分:6)

我设法用paperclip interpolations解决了这个问题:

  1. 在模型中定义一个字段,将存储上传文件的路径
  2. 通过属性更新
  3. 将回形针附件信息加载到DB
  4. 使用插值指定回形针附件:路径,因此它首先查找上传的文件,然后默认
  5. 利润!
  6. 由于how S3 storage composes urls

    ,这可以解决问题
      

    路径:这是存储文件的存储区下的密钥。 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
    })
    

答案 1 :(得分:0)

<强> S3

Paperclip S3 integration实际上相对简单 - 您最好关注如何使用Paperclip的this Railscast,以及上述相关文档,让您了解Paperclip的工作原理;然后你可以将它连接到S3

-

简而言之,Paperclip基本上是一个文件对象&amp;将相关数据保存到您的数据库。该文件的存储取决于您与Paperclip

关联的服务

我想说的是两个元素(数据分配和文件存储)是gem的两个不同元素,如果你可以让Paperclip来处理入站文件,你就是一半那里:


<强>回形针

默认实施:

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

这样您就可以保存&#34;附件&#34;到你的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 %>

这将直接处理Paperclip上传到您自己的应用程序(将文件存储在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

<强>路径

如果您想致电&#34; S3&#34;文件的文件路径 - 你必须这样做:

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