ruby Rails将Active Storage从Image Magick迁移到Libvips,无需重新生成图像

vbopmzt1  于 2023-11-18  发布在  Ruby
关注(0)|答案(1)|浏览(107)

我们有一个Rails 7系统,其中大约有50,000张照片存储在Active Storage中,我们使用variant将其转换为不同的大小。目前,我们使用Image Magick作为image_processing的后端,我们希望更改为libvips,这也是最新Rails版本的默认设置(例如,请参阅this
不幸的是,传递给variant的选项哈希需要在我们的应用程序中为libvips更改。例如:(以及更多的示例here

variant(format: :jpg, strip: true, quality: 80) # imagemagick
variant(format: :jpg, saver: { strip: true, quality: 80 }) # libvips / image_processing

字符串
Rails在内部使用这个哈希值来唯一地标识变量。因此,如果我们改变变量描述以适应libvips,这将导致Rails重新生成100,000个图像,如果不是更多的话,这显然是我们想要避免的。
这个问题有没有标准的解决方案?
我考虑的一个选择是首先测试imagemagick变体是否已经存在,如果存在,就使用它,如下所示:

def create_variant
  magick_variant = image.variant(format: :jpg, strip: true, quality: 80)
  return magick_variant.processed.url if magick_variant.processed?
  
  image.variant(format: :jpg, saver: { strip: true, quality: 80 }).processed.url
end


遗憾的是,VariantWithRecord#processed?在Rails 7.1中被私有化了,因此不是一个可持续的解决方案。

y4ekin9u

y4ekin9u1#

我们通过收集我们使用的变体转换的大部分(大约80%)来进行迁移,在迁移之前和之后计算它们的转换表,然后手动更新存储在active_storage_variant_records中的转换表。
举例来说:

UPDATE `active_storage_variant_records` 
SET `variation_digest` = CASE `variation_digest`
   WHEN '8HYTSoAKrOz5PQZaB5rF21hDWks=' THEN 'ols+mvCHaSFFmjPwGcc9zwr6A6Y='
   WHEN 'LzJ443LpJ9ZNnqCVgpoG3j43nC0=' THEN 'Safska55MupNqvs4kO2JOJxLNoU='
END
WHERE `active_storage_variant_records`.`variation_digest` 
IN ('8HYTSoAKrOz5PQZaB5rF21hDWks=', 'LzJ443LpJ9ZNnqCVgpoG3j43nC0=');

字符串
这是因为VariantRecord再次使用has_one_attached,并且存储变体blob的密钥独立于摘要。

相关问题