The easiest way to add photos to your Rails app and attach them to your models.
SimplestPhoto ...
- is dead simple to use
- is easy to change—migrations and models live in your app and you can do whatever you want to them
- caches your Dragonfly-processed images for you
- Requires Rails >= 5.1. For prior versions, use the
0.1.0
release.
-
Add it to your
Gemfile
andbundle install
that thing. -
Generate the Dragonfly config:
rails generate dragonfly
-
Generate the models and migrations:
rails generate simplest_photo
-
Do some
rake db:migrate
-
Configure your models:
class Dinosaur < ActiveRecord::Base extend SimplestPhoto::HasPhoto has_photo :hero, required: true has_photo :centerfold end
-
Update your Dragonfly config to generate
PhotoCropping
s:# config/initializers/dragonfly.rb Dragonfly.app.configure do SimplestPhoto::UrlHelper.install(self) end
SimplestPhoto contains three models:
Photo
: the core photo model, where the Dragonfly attachment actually happens.PhotoAttachment
: the join table that connects aPhoto
with the things it is attached to.PhotoCropping
: model used to cache processed images.
PhotoCropping
needs a bit of explanation. When you ask Dragonfly for an image at 400x400#
, it generates a unique job URL for that image. When that job URL is requested, Dragonfly does the processing, sends down the image, and then forgets about it. This is no good in production.
SimplestPhoto caches these processed photos by tapping into Dragonfly's URL method. When a new job comes in, SimplestPhoto checks for any PhotoCropping
s with that job ID. If it finds one, it generates the URL to the stored image and sends that back. If it doesn't find one, it processes the image, stores it, inserts a new PhotoCropping
record with that job ID, and sends down the processed image. The next time that job URL is generated, SimplestPhoto will use the stored image and skip the processing. Groovy.
Suppose you have this model:
class Monster < ActiveRecord::Base
extend SimplestPhoto::HasPhoto
has_photo :headshot, required: true
end
SimplestPhoto generates this:
class Monster < ActiveRecord::Base
extend SimplestPhoto::HasPhoto
has_one :headshot_attachment,
-> { where(attachable_name: :headshot) },
as: :attachable,
class_name: 'PhotoAttachment',
dependent: :destroy
has_one :headshot
through: :headshot_attachment,
source: :photo
validates :headshot, presence: true
end
Standard stuff. It also defines #headshot_id
and #headshot_id=
accessors, which are what you should use in a form:
f.input :headshot_id, collection: Photo.all
To customize the valid image file extensions (which defaults to allowing .jpg
, .jpeg
, or .png
extensions), override the valid_image_extensions
method in the generated Photo
model:
class Photo < ActiveRecord::Base
def valid_image_extensions
%w(jpg jpeg png gif)
end
end
Visit code.viget.com to see more projects from Viget.