简体   繁体   English

如何在 Rails / Paperclip / S3 上更新 Ruby 中的文件?

[英]How can you update a file in Ruby on Rails / Paperclip / S3?

My Ruby on Rails application uses S3 and Paperclip.我的 Ruby on Rails 应用程序使用 S3 和 Paperclip。 I have users upload a text file, which works fine.我让用户上传了一个文本文件,效果很好。 I also want to allow them to edit the text file and resave it... this is where I'm confused.我还想让他们编辑文本文件并重新保存它......这就是我感到困惑的地方。 Since they're not re-uploading any file, but rather EDITING the contents of the saved text file.因为他们没有重新上传任何文件,而是编辑保存的文本文件的内容。 How can I do this?我怎样才能做到这一点?

Equivalently, how do you create / save a model with Paperclip, without uploading an actual file?同样,如何在不上传实际文件的情况下使用 Paperclip 创建/保存 model?

Here's something I tried...这是我尝试过的东西...

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 - I'm saving the files on S3 instead of a database blog because they could potentially be large, and that seems unsuited for a database. PS - 我将文件保存在 S3 而不是数据库博客上,因为它们可能很大,而且似乎不适合数据库。

EDIT: I'm adding a bounty that I'll award to anyone who can show me how to do this without requiring the user to save a text file and reupload it.编辑:我正在添加一个赏金,我将奖励给任何可以向我展示如何做到这一点而无需用户保存文本文件并重新上传它的人。 I have a HTML textarea and want to offer an AJAXed "Save" button to resave a text file on S3.我有一个 HTML textarea 并希望提供一个 AJAXed“保存”按钮来重新保存 S3 上的文本文件。

Sounds like you are mixing two conceptually different approaches: DB store and file store.听起来您正在混合两种概念上不同的方法:数据库存储和文件存储。 So from my point of view, you should go for either one of the 2 options:因此,从我的角度来看,您应该 go 用于以下两个选项之一:

Option 1: Use a file storage (like Amazon S3)选项 1:使用文件存储(如 Amazon S3)

This seems to be answered thoroughly by Ben Simpson.本辛普森似乎彻底回答了这个问题。 If you want to allow the user to edit a file-backed resource, then you have to make sure to "manipulate the contents of the file on S3 outside of Paperclip."如果您想允许用户编辑文件支持的资源,那么您必须确保“在 Paperclip 之外操作 S3 上的文件内容”。

Option 2: Use db-storage选项 2:使用 db-storage

It sounds to me like this is what you ultimately want to achieve.在我看来,这就是您最终想要实现的目标。 The file upload serves as the entry point for user-created content into your application.文件上传充当用户创建的内容进入您的应用程序的入口点。 Since you are dealing with simple text files, I suggest saving the uploaded file's contents into your model, which you can then update just like any other model (including your ajax save).由于您正在处理简单的文本文件,我建议将上传文件的内容保存到您的 model 中,然后您可以像任何其他 model 一样对其进行更新(包括您的 Z2705A83A5A0659CCE34583972637EDA 保存)。

For the initial values, ie "This is a sample text file. Edit and resave to change this.", you can either use the:default option in the migration file, or if you insist on a physical file to be present, use paperclip:default_url on the has_attached_file method along with a file that includes the template content.对于初始值,即“这是一个示例文本文件。编辑并重新保存以更改它。”,您可以使用迁移文件中的:default 选项,或者如果您坚持要存在物理文件,请使用回形针has_attached_file 方法上的 :default_url 以及包含模板内容的文件。

Assuming that you are using the aws-s3 gem, then you simply use that gem's API (not paperclip) to update the file:假设您使用的是 aws-s3 gem,那么您只需使用该 gem 的 API(不是回形针)来更新文件:

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

Since you are working with a file (multipart/form-data), you cannot display this data using HTML form fields.由于您正在处理文件(多部分/表单数据),因此无法使用 HTML 表单字段显示此数据。 In order for a user to "edit" a text file would be to download the file, make changes and save, then upload the new file again.为了让用户“编辑”文本文件,需要下载文件、进行更改并保存,然后再次上传新文件。

In your responding controller's update action, you will need to update the attributes of the Source instance with the new params.在响应控制器的更新操作中,您需要使用新参数更新 Source 实例的属性。 This new file will result in the Paperclip gem overwriting the information for the old file, and replacing it with the new file.这个新文件将导致 Paperclip gem 覆盖旧文件的信息,并将其替换为新文件。 Assuming you are using the Rails form_for method, and the Paperclip helpers:假设您使用的是 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 will send Amazon S3 a request to remove the old file, and save the new file. Paperclip 将向 Amazon S3 发送删除旧文件并保存新文件的请求。

If you want to display the contents of this file to the user after they have finished uploading, you can do so via an HTML form element such as a text field, or text area.如果您想在用户上传完成后向用户显示该文件的内容,您可以通过 HTML 表单元素(例如文本字段或文本区域)来实现。 You will need to manipulate the contents of the file on S3 outside of Paperclip.您将需要在 Paperclip 之外的 S3 上操作文件的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM