FileColumn: regenerate images
If you change the images dimensions or introduce a new version for models using file column you need a way to update the existing ones.
Here is a script that will regenerate all file column images and its version. We still look for a way to generate only new versions.
# recreates all file_column images in all needed sizes
class ImageUpdater
def update_all
update_model(:user, :photo)
update_model(:auto, :photo)
update_model(:photo, :file)
update_model(:group, :photo)
end
private
def update_model(class_name, attribute_name)
eval(class_name.to_s.capitalize).find(:all).each {|instance|
begin
dir = instance.send(attribute_name)
unless dir.blank?
instance.send(“#{attribute_name}=”, upload(dir))
instance.save!
end
rescue Exception => e
puts e.message
end
}
end
# copied from file_column/test_case.rb
def upload(path, content_type=:guess, type=:tempfile)
if content_type == :guess
case path
when /\.jpg$/ then content_type = “image/jpeg”
when /\.png$/ then content_type = “image/png”
else content_type = nil
end
end
uploaded_file(path, content_type, File.basename(path), type)
end
def uploaded_file(path, content_type, filename, type=:tempfile) # :nodoc:
if type == :tempfile
t = Tempfile.new(File.basename(filename))
FileUtils.copy_file(path, t.path)
else
if path
t = StringIO.new(IO.read(path))
else
t = StringIO.new
end
end
(class << t; self; end).class_eval do
alias local_path path if type == :tempfile
define_method(:local_path) { “” } if type == :stringio
define_method(:original_filename) {filename}
define_method(:content_type) {content_type}
end
return t
end
end
Tags: file_column, rails, regnerate-images, script




August 19th, 2007 at 20:30
Great workaround Thilo!
I apologize if this is a trivial question, but how would one integrate this into their Rails site? It seems like there would be several possibilities, so how would you do it?
August 21st, 2007 at 09:09
We don’t integrate the script in our site. We ran it on demand. Because it regnerate all images. This puts serious load on our serve ran took a couple of days.
If you need new inmage versions on demand it is better to use: url_for_image_column. It checks if a version exitst and renerate it if not. But it can’t update geometrie of existing versions. Hope that helps.
August 25th, 2007 at 09:04
Thanks Thilo!
I had never heard of url_for_image_column before. Once I started searching for it, the only good documentation I found was in the source files themselves. That has accomplished exactly what I needed.
September 6th, 2007 at 23:32
There are some conditions as to whether url_for_image_column will regenerate a new image version on the fly. File_column places the master version in the directory:
model_name/column_name/record_id/image_name.ext
Alternate named versions like ‘thumb’ will be placed in the same directory but in a folder of the same version name:
model_name/column_name/record_id/thumb/image_name.ext
Now, if you delete the image in the thumb directory, no new image will be regenerated. You just get a broken link. If however, you delete the thumb directory entirely, url_for_image_column will attempt to generate a new named version for you. However, it is not smart enough to determine the size from the versions information defined in the model, you must specify the crop and size options in the url_for_image_column parameters.
September 7th, 2007 at 11:13
Hi Homan, thanks for your insight. Are u sure that it can’t access the version information? Because I have to provide the model object anyway (e.g. url_for_image_column(@auto, ‘photo’, :badge_5) . And as far a I can see it always ends up in create_magick_version_if_needed. And it works just fine for us, deleting just specific versions. Because it checks each version, as it can be seen in the above mentioned method, here ‘File.exists?(absolute_path(version_options[:name]))’. We just use it in one case, so maybe it just works by coincident. But I hope not
February 6th, 2008 at 15:31
I changed class_name.to_s.capitalize to class_name.to_s.classify, because calling update_model(:common_page_asset, :asset) was not working with capitalize. Maybe i misunderstood your parameter convention or the script has to be changed when using model names with underscores. However, thanks for the script!
February 10th, 2008 at 21:49
i think you are right. capitalize works as long as the class name only consists of one word, which has been the case for all our classes so far.
February 5th, 2009 at 17:28
Very informative article, which I found quite useful. Cheers ,Jay