【问题标题】:How can you update a file in Ruby on Rails / Paperclip / S3?如何在 Ruby on Rails / Paperclip / S3 中更新文件?
【发布时间】:2011-07-16 02:25:01
【问题描述】:

我的 Ruby on Rails 应用程序使用 S3 和 Paperclip。我让用户上传了一个文本文件,效果很好。我还想让他们编辑文本文件并重新保存它......这就是我感到困惑的地方。因为他们没有重新上传任何文件,而是编辑保存的文本文件的内容。我该怎么做?

同样,您如何在不上传实际文件的情况下使用 Paperclip 创建/保存模型?

这是我尝试过的……

Source.new(:user_id => 4,
           :name => "untitled.txt",
           :attachment_file_name => "untitled.txt",
           :attachment_content_type => "application/octet-stream",
           :attachment_contents => "This is a sample text file. Edit and resave to change this.")
      .save

PS - 我将文件保存在 S3 而不是数据库博客上,因为它们可能很大,而且似乎不适合数据库。

编辑:我正在添加一个赏金,我将奖励给任何可以向我展示如何做到这一点而无需用户保存文本文件并重新上传它的人。我有一个 HTML 文本区域并想提供一个 AJAXed“保存”按钮来重新保存 S3 上的文本文件。

【问题讨论】:

  • 你在使用aws-s3 gem吗?

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


【解决方案1】:

听起来您正在混合两种概念上不同的方法:数据库存储和文件存储。因此,从我的角度来看,您应该选择以下两个选项之一:

选项 1:使用文件存储(如 Amazon S3)

Ben Simpson 似乎彻底回答了这个问题。如果您想允许用户编辑文件支持的资源,那么您必须确保“在 Paperclip 之外操作 S3 上的文件内容。”

选项 2:使用 db-storage

在我看来,这就是您最终想要实现的目标。文件上传充当用户创建的内容进入您的应用程序的入口点。由于您正在处理简单的文本文件,我建议将上传文件的内容保存到您的模型中,然后您可以像任何其他模型(包括您的 ajax 保存)一样对其进行更新。

对于初始值,即“这是一个示例文本文件。编辑并重新保存以更改它。”,您可以使用迁移文件中的 :default 选项,或者如果您坚持存在物理文件,在 has_attached_file 方法上使用回形针 :default_url 以及包含模板内容的文件。

【讨论】:

  • 你说得对,我不确定文件存储是否是最佳选择,但我倾向于它的原因是 1) 你将能够上传其他类型的文件,而不仅仅是 txt 文件,并且 2) 我可能想将 Amazon Elastic MapReduce 与其他文件结合使用,所以我认为如果它们都在 Amazon 上会很好。这有意义吗?
  • Jeff,我对 Amazon Elastic MapReduce 没有任何经验,但我知道它是某种海量处理和分析服务。鉴于此,我认为答案很大程度上取决于您的应用程序的要求。您也应该能够在您的数据库中进行大量的海量数据分析——但话说回来,您又错过了该服务的好处。我的建议:考虑一下对您的应用程序至关重要的东西,看看一个简单的 db-backed 解决方案是否适合您。如果没有,您仍然可以选择将信息保存在您的数据库中并将其异步镜像到 S3。
  • 我想我现在只使用 db-storage 并镜像它。谢谢。您对 Rails 迁移符号使用什么有任何建议,也许是 :binary?
  • 很高兴听到我的回答有帮助。关于迁移文件中属性的类型,答案取决于您想要支持的其他文件类型。如果它只是文本(可能包括您在文件上传时处理的一些 RTF 格式),我会选择 :text -> 应该比 :binary 更容易处理。如果您想将整个文件存储在 db 中, :binary 将是合适的(但您只希望它的内容在 db 中,对吧?)
【解决方案2】:

假设您使用的是 aws-s3 gem,那么您只需使用该 gem 的 API(不是回形针)来更新文件:

AWS::S3::S3Object.store 's3/path/to/untitled.txt', params[:textarea_contents_params_name], your_bucket_name

【讨论】:

    【解决方案3】:

    由于您使用的是文件(multipart/form-data),因此您无法使用 HTML 表单字段显示此数据。为了让用户“编辑”文本文件,需要下载文件、进行更改并保存,然后再次上传新文件。

    在响应控制器的更新操作中,您需要使用新参数更新 Source 实例的属性。这个新文件将导致 Paperclip gem 覆盖旧文件的信息,并将其替换为新文件。假设您使用的是 Rails form_for 方法和 Paperclip 助手:

    # app/controllers/source_controller.rb
    class SourceController < ApplicationController
      def update
        @source = Source.find(params[:id])
        @source.update_attributes(params[:source]) # This will overwrite the old file information
      end
    end
    

    Paperclip 将向 Amazon S3 发送删除旧文件并保存新文件的请求。

    如果您想在用户上传完成后向用户显示该文件的内容,您可以通过 HTML 表单元素(例如文本字段或文本区域)来实现。您将需要在 Paperclip 之外的 S3 上操作文件的内容。

    【讨论】:

    • 你是对的,我在 textarea 中显示内容。但是您确定需要在 Paperclip 之外操作内容,然后重新上传吗?当然有一种方法可以在浏览器中完全在线完成!
    • 您所说的“肯定有一种方法可以在浏览器中完全在线执行此操作!”是什么意思?用户提交更改的文本,您将其包装在一个文件中,然后将其发送到 S3。对我来说,这一切似乎都在浏览器中。
    • 我想我的意思是——实际文件是否必须存在于某处,例如服务器创建的临时文件?或者您可以像我尝试使用我的代码那样完全绕过它吗?
    猜你喜欢
    • 2010-11-23
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 2015-12-15
    • 2014-03-22
    • 1970-01-01
    相关资源
    最近更新 更多