【问题标题】:Carrierwave doesn't recreate versions after the model updateCarrierwave 不会在模型更新后重新创建版本
【发布时间】:2019-02-17 18:40:16
【问题描述】:

我在我的 Carrierwave Uploader 上引入了一个新版本。当我创建一个新的Event 时,它会正确创建两个版本。但是当我更新它时,只会上传我附加的文件,但不会重新创建版本。

我正在使用CarrierWave 1.2.2,查看更新日志,它似乎不是在较新版本中修复的错误

class CoverUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  if Rails.env.development? || Rails.env.test?
    storage :file
  elsif Rails.env.production?
    storage :fog
  end

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    if ENV['HEROKU_APP_NAME'].to_s.include?('-pr-')
      "review_apps/#{model.class.to_s.underscore}/#{model.id}"
    else
      "#{Rails.env}/#{model.class.to_s.underscore}/#{model.id}"
    end
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  def default_url(*args)
    ActionController::Base.helpers.asset_path('test.jpg')
  end

  # Create different versions of your uploaded files:
  version :optimised do
    process convert: 'webp'
    process :set_content_type_to_webp

    def full_filename(_for_file = model.cover.file)
      "cover_#{model.id}.webp"
    end

    def exists?
      file&.exists?
    end
  end

  def extension_blacklist
    %w(webp)
  end

  private

  # Required to actually force Amazon S3 to treat it like an image
  def set_content_type_to_webp
    file.instance_variable_set(:@content_type, 'image/webp')
  end
end

【问题讨论】:

  • 也许您正在寻找 Carrierwave 提供的 recreate_versions! 命令 (github.com/carrierwaveuploader/carrierwave#recreating-versions)?
  • 我想它会起作用,但我期待 update 为我做这件事。更重要的是,它似乎以某种方式被调用,因为在保存新图像后,旧的 :optimized 版本消失了,剩下的就是标准的新上传的图像。这又不是我所期望的行为,我还没有在另一个做类似事情的项目上看到这个问题@AnujKhandelwal
  • 请更新载波版本
  • @ogelacinyc 我检查了更新日志,自从我的版本 - 1.2.2 以来,没有任何改变可能会影响到这一点。我可以尝试升级,因为这并没有什么坏处,但这只是一个随机的建议还是你真的有什么想法?
  • @MaximFedotov 不。有某种误解。我的评论的意思是评论您当前的载波版本。对此我很抱歉。

标签: ruby-on-rails ruby ruby-on-rails-5 carrierwave


【解决方案1】:

@ogelacinyc 在发现full_filename 中的错误时部分正确。我通过创建另一个版本返回测试正常功能,并进行了简单的尺寸更改。然后我可以看到更新会自行重新创建版本,就像我预期的那样。

这让我觉得我的version :optimised 块可能有问题。所以一一评论后发现full_filename才是罪魁祸首。可能是model.cover.file 默默地失败了,但我认为是model.id,如filename method in Carrierwave 的描述中所示

因此,我直接获取文件名,提取扩展名并将其替换为 webp:

  def full_filename(for_file = model.file_name.file)
    extension = File.extname(for_file)
    "cover_#{for_file.sub(extension, '.webp')}"
  end

没有问题!

【讨论】:

    【解决方案2】:

    您需要向 Event 添加一个 after_save 回调,然后在已挂载的上传器上调用 recreate_versions!

    假设您有一个具有以下内容的事件模型,这将解决您的问题。

    class Event < ApplicationRecord
      mount_uploader :cover_image, CoverUploader
      after_save :recreate_versions!
      delegate :recreate_versions!, to: :cover_image, allow_nil: true
    end
    

    另见CarrierWave's README

    【讨论】:

    • 就是这样,我认为这不是必需的,我想避免在可能不需要时添加回调。在我参与的另一个项目中,版本会在更新时重新创建,而无需添加任何其他内容。这就是我希望它起作用的方式......
    • 那么我能给你的最好建议是定义一个名为 recreate_versions_if_needed! 的私有方法,然后仅有条件地调用 cover_image.recreate_versions!。我只是不太了解您的特定应用要求,无法建议这些条件应该是什么。
    • 当然可以,但是你需要吗?我的问题可以归结为:上传新图像时,CarrierWave 会自动重新创建版本吗?我理解它确实如此,因此试图理解为什么它不在我的应用程序中。据我所知,我没有做任何不寻常的事情。我宁愿找到问题的根源并正确解决它,也不愿像添加此回调这样的权宜之计
    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多