Rails: Carrierwave recreation versions do not change old images

My Rails uses carrier management to control image loading. I have watermarked images on my site. I used to overlay an image on them, for example:

def watermark manipulate! do |img| logo = Magick::Image.read("#{Rails.root}/public/images/plc-watermark.png").first img = img.composite(logo, Magick::SouthEastGravity, Magick::OverCompositeOp) end end 

Now I overlay the text, for example:

 def watermark manipulate! do |img| text = Magick::Draw.new text.gravity = Magick::CenterGravity text.pointsize = 12 text.font = "#{Rails.root}/public/fonts/hn300.ttf" text.stroke = 'none' text.annotate(img, 0, 0, 0, 0, "Photo © #{model.user.full_name}\nHosted by Placeology.ws\nPlease log in to remove this watermark") img end end 

Now it works for new images, but when I call rereate_versions! old photos are not replaced. How can I use this new watermark to replace the old one?

Why do I use Fog with Amazon S3 for storage both in development and in production.

+4
source share
2 answers

It may not be the same at all, but for googleability:

We have a random hash in the file name, similar to what is described in this discussion thread .

When restoring images, it will generate new images using the new hash, but it will not update the file name stored in the database, so it will try to display the images with the old names.

This reproduces the problem:

 bundle exec rails runner "Foo.find(123).images.each { |img| uploader = img.image; puts %{before: #{img.image.inspect}}; uploader.recreate_versions!; puts %{after: #{img.reload.image.inspect}} }; p Foo.find(123).images" 

It gives a conclusion, for example

 before: /uploads/foo_123_6a34e47ef5.JPG after: /uploads/foo_123_d9a346292d.JPG [#<Image id: 456, foo_id: 123, image: "foo_123_6a34e47ef5.JPG">] 

But the addition of img.save! after reconstituting the versions fixes it:

 bundle exec rails runner "Foo.find(123).images.each { |img| uploader = img.image; puts %{before: #{img.image.inspect}}; uploader.recreate_versions!; img.save!; puts %{after: #{img.reload.image.inspect}} }; p Foo.find(123).images" 

With an exit:

 before: /uploads/foo_123_6a34e47ef5.JPG after: /uploads/foo_123_d9a346292d.JPG [#<Image id: 456, foo_id: 123, image: "foo_123_d9a346292d.JPG">] 

Edit:

Actually, the above worked with files on the disk, but not with fog. To make everything easy for myself, I ended up just recreating the images and deleting the old ones:

 Image.all.each { |old| new = Image.new(foo_id: old.foo_id, image: old.image) new.save! old.destroy } 
+8
source

You need to call image.cache_stored_file! before calling recreate_versions!

This is strange because the method itself calls it if the file is cached, but for some reason it did not work.

+3
source

Source: https://habr.com/ru/post/1369017/


All Articles