简体   繁体   中英

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

My Ruby on Rails application uses S3 and 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?

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.

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.

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:

Option 1: Use a file storage (like 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."

Option 2: Use 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).

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.

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::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. 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. This new file will result in the Paperclip gem overwriting the information for the old file, and replacing it with the new file. Assuming you are using the Rails form_for method, and the Paperclip helpers:

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

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. You will need to manipulate the contents of the file on S3 outside of Paperclip.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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