Ben Downey
Ben Downey

Reputation: 2665

S3 upload in fewest possible steps

So I setup my app to upload documents to S3 (following Ryan Bates' railscast). Currently, there's a form to upload a file is on the index page for the document resource. On successful upload to S3, that form renders the new actions where the user can rename the file (as it's named locally).

But I'd like to refactor this to eliminate redirecting the user to the '/new' page. I don't want to offer the user a chance to rename the file.

There's got to be a way to upload the file to S3 and then have it post to the create action.

This is what my controller looks like now.

class DocumentsController < ApplicationController

  before_filter :authenticate_user!

  def index
    @page_title = "Docs"
    @documents = household.documents.all
    @uploader = Document.new.file_upload
    @uploader.success_action_redirect = new_document_url
  end

  def new
    @page_title = "New Doc"
    @document = Document.new(household_id: household.id, key: params[:key])
  end

  def create
    @doc = Document.new(params[:document])
    if @doc.save
      flash[:notice] = "Consider it done!"
      redirect_to documents_path
    else
      flash[:notice] = "Oops. Please try again."
      render 'new'
    end
  end
end

How do I simplify this situation and avoid rendering the /new page? Instead of rendering the /new, I want to just post to the create action. I need modify this line:

@uploader.success_action_redirect = new_document_url

but I don't know what it should be.

Upvotes: 0

Views: 44

Answers (1)

Vidya
Vidya

Reputation: 30310

Perhaps you can create a method in DocumentsController that serves as a REST endpoint. You post from the client via Ajax and then upload to S3 in the endpoint method. This way the client's experience remains unchanged with the upload.

Something like this:

def upload
    uploader = Document.new(params_from_ajax_post).file_upload
    respond_to do |format|
      format.html { render :json => {:message => 'Upload successful.'} }
    end
end

In routes.rb:

match 'documents/upload' => 'documents#upload', :via => :post, :as => 'upload'

Upvotes: 1

Related Questions