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 开发者_Python百科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, i.e. "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.
精彩评论