【问题标题】:Saving my ActiveRecord model deletes my CarrierWave image versions保存我的 ActiveRecord 模型会删除我的 CarrierWave 图像版本
【发布时间】:2013-01-22 15:38:40
【问题描述】:

每当我使用已安装的上传器保存模型时,只要我保存它,版本就会被删除(并且看起来好像在正常上传图像时甚至没有创建版本)。请注意,直到几天/几周前它才能正常工作(我没有注意到确切的时间,尽管它可能是通过迁移到 Rails 3.2.11 发生的。我之前是 3.2.8)。

我的模型是这样定义的:

class Profile < ActiveRecord::Base
  attr_accessible :profile_picture
  mount_uploader :profile_picture, ProfilePictureUploader
  ...
end

还有我的ProfilePictureUploader

class ProfilePictureUploader < BaseUploader
  process :resize_to_fill => [248, 248]

  version :tiny do
    process :resize_to_fill => [34, 34]
    def full_filename(for_file = model.photo.file)
      "#{model.to_s.parameterize}_tiny.jpg"
    end
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here, see uploader/store.rb for details.
  def filename
    # John Snow -> john-snow-20120913162935.jpg
    # ACME inc. -> acme-inc-20120913162935.png
    "#{model.to_s.parameterize}-#{Time.now.strftime("%Y%m%d%H%M%S")}#{File.extname(original_filename)}" if original_filename
  end
end

最后是我的BaseUploader

class BaseUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
  include Sprockets::Helpers::RailsHelper
  include Sprockets::Helpers::IsolatedHelper

  # Override the directory where uploaded files will be stored.
  def store_dir
    "system/uploads/#{model.class.to_s.underscore}/#{model.id}"
  end

  # Override the filename of the uploaded files:
  def filename
    "#{mounted_as}#{File.extname(original_filename)}" if original_filename
  end
end

我在开发中使用文件存储,在生产中使用雾存储,但在这两种环境中都会出现问题,所以我们假设它正在使用文件存储。

这是我的典型场景:

  • 我将图片上传到个人资料,只创建标准图片(例如:mbillard-20130122102833.jpg)。
  • 我在个人资料图片上调用recreate_versions!,标准图像和小版本都被创建(由于我的特殊命名方案而重新创建了标准,我很好)。
  • 我保存了我的模型,文件夹 (system/uploads/profile/1/) 中的所有内容都被删除,除了文件名为 profile_picture 属性的图像。

我使用的是carrierwave 0.8.0。我相信它与保存触发器有关,但通过查看代码无法弄清楚。

(我也同时开了一个GitHub issue

【问题讨论】:

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


    【解决方案1】:

    我终于明白了。基本上,mount.rb 中的 remove_previously_stored_#{column} 方法似乎删除了我新创建的版本,因为它们与以前的版本具有相同的名称。

    我修改了我的小版本文件名以包含时间戳(这样它就不会与之前的小版本具有相同的文件名):

    version :tiny do
      process :resize_to_fill => [34, 34]
      def full_filename(for_file = model.photo.file)
        "#{model.to_s.parameterize}_#{timestamp}_tiny.jpg"
      end
    end
    

    我简化了我的 filename 逻辑以简单地定义带有时间戳的文件名:

    # Override the filename of the uploaded files:
    # Avoid using model.id or version_name here, see uploader/store.rb for details.
    def filename
      # John Snow -> john-snow-20120913162935.jpg
      # ACME inc. -> acme-inc-20120913162935.png
    
      "#{model.to_s.parameterize}-#{timestamp}#{File.extname(original_filename)}" if original_filename.present?
    end
    

    我的时间戳函数要么从文件名中提取时间戳,要么在重新创建版本或上传新文件时生成一个新的时间戳(当 original_filename 存在时):

    protected
    
    def timestamp
      if original_filename.blank?
        match_data = /^.+-(\d{14})\.\D{3,4}$/.match(File.basename(model.read_attribute(mounted_as)))
    
        return match_data[1] if match_data
      end
    
      var = :"@#{mounted_as}_timestamp"
      model.instance_variable_get(var) || model.instance_variable_set(var, Time.now.strftime("%Y%m%d%H%M%S"))
    end
    

    请注意,之前的时间戳可以存储在我的模型的属性中,但这对我有用。

    现在唯一让我烦恼的是我必须保存我的模型,以便在重新创建版本时删除以前的文件。

    model.recreate_versions! # recreates versions but leaves the previous files there
    model.save # removes the previous files
    

    你可以在GitHub issue看到我的整个思考过程。

    【讨论】:

      猜你喜欢
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多