On-the-fly disk caching of paperclip widths and height (attachment_fu migration support)

7 views
Skip to first unread message

Julian Harris

unread,
Sep 14, 2009, 12:08:46 AM9/14/09
to Paperclip Plugin, jul...@julianonsoftware.com
Problem: unlike attachment_fu, Paperclip doesn't know what the width
or height is of an individual 'style' of image.

There was another thread discussing how to do this; edgarjs came up
with a method that loads the geometry from disk via a system call
every time. For some reason I can't reply to the original thread so
here's an initializer I have used that builds on edgarjs's work with a
db caching wrapper.

Intent: you would add specific style width height values you want to
access ONLY, and no others. This is because most of the time you don't
need these values. In my case I only need the height of a specific
style for css layout reasons.

I'm not sure exactly whether this is the best way -- I ended up
calling instance.save which is a little risky but anyone closer to the
code could perhaps suggest a more effective way?

Also, no tests provided yet. Any ideas best way to test this
appreciated too.


--------


# on-demand width and height caching of paperclip images.
# looks for property and if not present, attempts to cache it to disk.
# Rails 2.0+: Stick this in config/initializers/
paperclip_image_size.rb
# NOTE as a side-effect, it calls instance.save the first time.
# this could cause a headache if you're in the middle of manipulating
content in the parent instance,
# by jul...@julianonsoftware.com / 14 Sep 09
# thanks to edgarjs for the code PaperClip::Geometry.from_file bits on
http://groups.google.com/group/paperclip-plugin/browse_thread/thread/50039909a58361e7

module Paperclip
class Attachment
def width(style = default_style)
return cached_property('width', style)
end

def height(style = default_style)
return cached_property('height', style)
end

protected

def cached_property(property, style)
raw_property = "#{style}_#{property}"
cached_value = instance_read(raw_property)
if cached_value.nil?
geometry = Paperclip::Geometry.from_file(to_file(style))
cached_value = geometry.send(property)
instance_write(raw_property, cached_value)

# YEP this writes the parent instance. Couldn't figure out how
to do this otherwise.
instance.save
RAILS_DEFAULT_LOGGER.debug "Paperclip::Attachment: can't find #
{raw_property} for '#{self.original_filename}', loading from disk and
caching in parent instance #{instance.inspect}"
end
return cached_value
end
end
end

Kennon Ballou

unread,
Sep 14, 2009, 2:05:53 AM9/14/09
to papercli...@googlegroups.com
By the way, my fork of paperclip includes saving the width/height of the
original image to the database if the fields <attachment_width/_height
are present. It even has tests (http://github.com/kennon/paperclip)

It might be slightly out of date from master but if so I'll merge soon.

Jonathan didn't want to merge this into master because he's trying to
keep any image-specific code out of the trunk and push them into
separate modules, etc.

| Kennon Ballou
| Angry Turnip, Inc.

Julian Harris

unread,
Sep 14, 2009, 3:10:37 AM9/14/09
to papercli...@googlegroups.com
Hi yes I saw that but I couldn't figure out which style the height and width was against. With the change I made, you can store height and width with an arbitrary number of image styles.
Reply all
Reply to author
Forward
0 new messages