Rails: воссозданные версии Carrierwave не изменяют старые образы

Приложение My Rails использует операторскую волну для управления загрузкой изображений. На моем сайте есть версии изображений с водяными знаками. Раньше я накладывал на них изображение, вот так:

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

Теперь я накладываю текст, например:

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

Теперь это работает для новых изображений, но когда я вызываю recreate_versions! старые фото не заменяются. Как я могу получить этот новый водяной знак вместо старого?

Что бы это ни стоило, я использую Fog с Amazon S3 для хранения как в разработке, так и в производстве.


person Andrew    schedule 25.08.2011    source источник


Ответы (2)


Это может быть не совсем та же проблема, но для удобства поиска в Google:

У нас есть случайный хэш в имени файла, аналогичный описанному в этой ветке обсуждения. .

При регенерации изображений он будет генерировать новые изображения, используя новый хэш, но не будет обновлять имя файла, хранящееся в базе данных, поэтому будет пытаться отобразить изображения со старыми именами.

Это воспроизводит проблему:

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"

Это дает вывод, как

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

Но добавление img.save! после воссоздания версий исправляет это:

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"

С выходом:

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

Изменить:

На самом деле вышеописанное работало с файлами на диске, но не с туманом. Чтобы облегчить себе задачу, я просто воссоздал изображения и удалил старые:

Image.all.each { |old|
  new = Image.new(foo_id: old.foo_id, image: old.image)
  new.save!
  old.destroy
}
person Henrik N    schedule 01.11.2011
comment
Это правильно определяет проблему, которая у меня была. В итоге я нашел немного другое решение, но это работает. - person Andrew; 11.11.2011
comment
Спасибо за предложение, у меня была аналогичная проблема. Исправление моей проблемы заключалось в том, чтобы убедиться, что новый сгенерированный файл имеет другое уникальное имя. - person Nathan Bertram; 07.09.2014
comment
Пришлось сделать это снова, сделал что-то вроде этого, чтобы восстановить все изображение (включая все версии) с туманом (S3): record.remote_image_url = record.image_url; i.save! - person Henrik N; 22.09.2014

Вам нужно позвонить image.cache_stored_file!, прежде чем звонить recreate_versions!

Это странно, потому что сам метод вызывает это, если файл закэширован, но по какой-то причине это не сработало.

person edgarjs    schedule 20.09.2011