Dragonfly

Image/asset management for winners

GitHub Repository

Using with Rails

Setup

Gemfile:

gem 'dragonfly', '~> 1.4.0'

Command line:

rails generate dragonfly

This generates a file in config/initializers/dragonfly.rb.
See Configuration for customizations.

Handling attachments

Supposing we have a Photo model that we wish to add an image attribute to.

Dragonfly provides the accessor by adding to the model

class Photo < ActiveRecord::Base
  dragonfly_accessor :image    # defines a reader/writer for image
  # ...
end

but it needs an image_uid column to work, so you’ll need a migration with

add_column :photos, :image_uid,  :string
add_column :photos, :image_name, :string  # Optional - if you want urls
                                          # to end with the original filename

or equivalent.

View for uploading:

<% form_for @photo do |f| %>
  ...
  <%= f.file_field :image %>
  ...
<% end %>

Rails < 3.2: You’ll need to add :html => {:multipart => true} to the form tag helper.

We need to allow the parameter image to be accepted by the controller.

In Rails 4, you’ll need

params.require(:photo).permit(:image)

or something similar in the controller, and in Rails 3

attr_accessible :image

in the model.

View for displaying:

<%= image_tag @photo.image.thumb('400x200#').url if @photo.image_stored? %>

More with models…

There are many more things you can do with models, such as making thumbnails on upload, or persisting attachments even when validations fail.
See Models for more details.

Caching

The simplest way to cache content in Rails is with Rack::Cache.

In your Gemfile, for production environment you should have

gem 'rack-cache', :require => 'rack/cache'

Then add Rack::Cache to the middleware stack in production environment. See below for how to do that for your Rails version.

Rails 4

Uncomment the line in config/environments/production.rb

config.action_dispatch.rack_cache = true

Rails 3.1 - 3.2

Nothing to do! Rack::Cache is already inserted for you in production.

Rails 2.3 - 3.0

in config/environments/production.rb

config.middleware.use 'Rack::Cache', {
  :verbose     => true,
  :metastore   => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/meta"),
  :entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
}

Custom endpoints

routes.rb:

Text generation example

get "text/:text" => Dragonfly.app.endpoint { |params, app|
  app.generate(:text, params[:text], 'font-size' => 42)
}

Endpoint callable from javascript. e.g. /image?file=egg.png&size=30x30

get "image" => Dragonfly.app.endpoint { |params, app|
  app.fetch_file("some/dir/#{params[:file]}").thumb(params[:size])
}