A Fresh Cup is Mike Gunderloy's software development weblog, covering Ruby on Rails and whatever else I find interesting in the universe of software. I'm a full-time Rails developer and contributor, available for long- or short-term consulting, with solid experience in working as part of a distributed team. If you'd like to hire me, drop me a line. I'm also the author of Rails Rescue Handbook and Rails Freelancing Handbook.

Navigation
« Double Shot #822 | Main | What's New in Edge Rails #9 »
Tuesday
Feb212012

Using CarrierWave and S3 with Mercury Editor

I've been using Mercury Editor in a new project to get editable text directly in the browser. By default, it stores images locally, but we wanted to put them on Amazon S3 instead. Here's what that took using CarrierWave:

Add a model to hold the images


class BlogImage < ActiveRecord::Base
  mount_uploader :image, ImageUploader
end

Not much to see here, just a single string attribute to hold the image info.

Add an uploader


require 'carrierwave/processing/mime_types'
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick
  include CarrierWave::MimeTypes
  process :set_content_type
  storage :fog
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end

Obviously you could process extra versions or limit extensions here, but all Mercury needs is someplace to dump what it takes in.

Replace the Mercury Images Controller

To hook everything up, you just need to replace the images controller in the engine with app/controllers/mercury/images_controller.rb in your project:


class Mercury::ImagesController < MercuryController

  respond_to :json

  def create
     @blog_image = BlogImage.new(params[:image])
     @blog_image.save!
     render :json => @blog_image.to_json(:only => :image)
  end

  def destroy
    @image = BlogImage.find(params[:id])
    @image.destroy
    respond_with @image
  end

end

Reader Comments (5)

Getting this error on upload
Excon::Errors::SocketError (Broken pipe (Errno::EPIPE)):
app/controllers/mercury/images_controller.rb:7:in `create'

The file is uploaded to s3 storage but there seems to be some sort of error on trying to create the BlogImage.

Here is the console before the error above

(0.1ms) begin transaction
SQL (0.3ms) INSERT INTO "blob_images" ("created_at", "image", "updated_at") VALUES (?, ?, ?) [["created_at", Tue, 28 Aug 2012 02:20:59 UTC +00:00], ["image", "thankyou.png"], ["updated_at", Tue, 28 Aug 2012 02:20:59 UTC +00:00]]
(0.4ms) rollback transaction

August 27, 2012 | Unregistered CommenterBenjamin

I just implemented mercury with carrierwave today and it was necessary to do some other updates as well. I thought I would mention that in the comments:

In the routes.rb:

namespace :mercury do
resources :images, :only => [:create,:destroy]
end

In the images_controller.rb:

def create
@image = BlogImage.new(params[:image])
@image.save!
render text: "{\"image\":{\"url\":\"#{@image.image.to_s}\"}}"
end

February 1, 2013 | Unregistered CommenterSandeep

That worked great for me, thanks!

The additional change in the render call that Sandeep describes wasn't necessary in my environment.

I removed the 'destroy' method, as it was never called by mercury. Instead, I added a separate view + controller to show and remove any uploaded image to the S3.
___
Rails v3.2.14, Ruby 2.0.0-p247

August 9, 2013 | Unregistered Commentermoreinput

I tried your example. However all I am getting in the parameters are {"action"=>"create", "controller"=>"mercury/images"} . Without any image around! params[:image] returns nil in my case. What kind of silly mistake could I have made? I am using Rails 3.2...

October 29, 2013 | Unregistered CommenterUmur Ozkul

Never mind. I discovered that I could not emulate using curl just...

October 29, 2013 | Unregistered CommenterUmur Ozkul

PostPost a New Comment

Enter your information below to add a new comment.
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>