8

私が取り組んでいる Web サイトは再設計中であり、そのため、ユーザー画像のサイズを変更する必要があります。Web サイトは現在、carrierwave gem を使用してすべての画像およびビデオ処理を処理しており、各画像には、次の内容に基づいた一意のファイル名を持つ元のファイルがあります。

def filename
  if original_filename
    if model && model.read_attribute(:user_image).present?
      model.read_attribute(:user_image)
    else
      @name ||= "#{secure_token}.#{file.extension}" if original_filename.present?
    end
  end
end

および secure_token によって生成される

def secure_token
  var = :"@#{mounted_as}_secure_token"
  model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end

これを行うために作成されるタスクは次のとおりです。

##
# CarrierWave Amazon S3 File Reprocessor Rake Task
#
# Written (specifically) for:
# - CarrierWave
# - Ruby on Rails 3
# - Amazon S3
#
# Works with:
# - Any server of which you have write-permissions in the Rails.root/tmp directory
# - Works with Heroku
#
# Not tested with, but might work with:
# - Ruby on Rails 2 
#
# Might work with, after a couple of tweaks:
# - File System Storage
# - Cloud Files Storage
# - GridFS
#
# Examples:
#
# Reprocess all versions of User#avatar
#  rake carrierwave:reprocess class=User mounted_uploader=avatar
#
# Reprocess the versions: thumb, small, medium for User#avatar
#  rake carrierwave:reprocess class=User mounted_uploader=avatar versions='thumb, small, medium'
#
# Reprocess for an underlying association, for things like Embedded MongoDB Documents
# which are models you cannot access directly, but rather through a regular Document
#
# Embeds One (picture) Association
#  rake carrierwave:reprocess class=User association=picture mounted_uploader=image versions='thumb, small, medium'
#
# Embeds Many (pictures) Association
#  rake carrierwave:reprocess class=User association=pictures mounted_uploader=image versions='thumb, small, medium'
#
# WARNING
# There is an issue with "Rake", that you cannot name your mounted_uploader "file".
# If you do this, then you will not be able to reprocess images through this rake task
#  class User
#    include Mongoid::Document
#    mount_uploader :file, PictureUploader
#  end
#
# This will NOT work with reprocessing through Rake because the mounted_uploader uses the "file" attribute.

namespace :carrierwave do

  ##
  # Only tested with Amazon S3 Storage
  # Needs some minor modifications if you want to use this for File System Store, Cloud Files and GridFS probably.
  # This should work without Ruby on Rails as well, just set a different TMP_PATH.
  desc "Reprocesses Carrier Wave file versions of a given model."
  task :reprocess => :environment do

    ##
    # Load in the OPEN URI library to be able
    # to pull down and store the original file in a temp directory
    require 'open-uri'

    ##
    # Default constants
    TMP_PATH          = "#{Rails.root}/tmp/carrierwave"

    ##
    # Set environment constants
    CLASS             = ENV['class'].capitalize
    ASSOCIATION       = ENV['association'] || nil
    MOUNTED_UPLOADER  = ENV['mounted_uploader'].to_sym
    VERSIONS          = ENV['versions'].nil? ? Array.new : ENV['versions'].split(',').map {|version| version.strip.to_sym}

    ##
    # Find the Model
    MODEL = Kernel.const_get(CLASS)

    ##
    # Create the temp directory
    %x(mkdir -p "#{TMP_PATH}")

    ##
    # Find all records for the provided Model
    records = MODEL.all

    ##
    # Output to console
    puts "\nCarrier Wave Version Reprocessing!"
    puts "======================================="
    puts "Model:              #{CLASS}"
    puts "Mounted Uploader:   #{MOUNTED_UPLOADER}"
    puts "Association:        #{ASSOCIATION}" if ASSOCIATION
    puts "Versions:           #{VERSIONS.empty? ? "all" : VERSIONS.join(', ')}\n\n"

    ##
    # Run through all records
    records.each do |record|

      ##
      # Set the mounted uploader object
      # If it has a one-to-one association (singular) then that object
      # will be returned and wrapped in an array so we can "iterate" through it below.
      # 
      # If it has a one-to-many association then it will return the array of associated objects
      #
      # If no association is specified, it assumes the amounted uploader is attached to the specified CLASS 
      if ASSOCIATION
        if ASSOCIATION.singular?
          objects = [record.send(ASSOCIATION)]
        else
          objects = record.send(ASSOCIATION)        
        end
      else
        objects = [record]
      end

      ##
      # Iterates through the objects
      objects.each do |object|

        ##
        # Returns the mounted uploader object
        mounted_object = object.send(MOUNTED_UPLOADER)

        ##
        # Retrieve Filename
        filename = mounted_object.path.split('/').last

        ##
        # Output to console
        puts "Reprocessing: #{filename}"

        ##
        # Read out the original file from the remote location
        # and write it out to the temp directory (TMP_PATH)
        # This file will be used as the base file to reprocess
        # the versions. Once all versions have been processed,
        # this temp file will be directly removed.
        open(mounted_object.url) do |original_object|
          File.open(File.join(TMP_PATH, filename), 'w') do |temp_file|
            temp_file.write(original_object.read)
          end
        end

        ##
        # By default it will add all available versions to the versions variable
        # which means that all available versions will be reprocessed.
        # If the "versions" argument has been provided, then only the specified
        # version(s) will be set to the versions variable, and thus, only these
        # will be reprocessed.
        versions = mounted_object.versions.map {|version| version[0]}
        versions = VERSIONS unless VERSIONS.empty?

        ##
        # Reprocesses the versions
        versions.each do |version|
          mounted_object.send(version).cache!(File.open(File.join(TMP_PATH, filename)))
          mounted_object.send(version).store!
        end

        ##
        # Removes the temp file
        %x(rm "#{TMP_PATH}/#{filename}")
      end
    end
  end
end

問題は、新しい画像を作成している間、ファイルが画像アップローダーで設定された命名に従うのではなく、新しいファイル名で保存されるため、Web サイトがそれらを見つけられないことです。以下は、画像の保存方法の例です。

それがどうあるべきか:

元のファイル: fdk392ks93_39ei.png

サムネイル版:thumb_fdk392ks93_39ei.png

それはどうですか:

元のファイル: fdk392ks93_39ei.png

サムネイル版:thumb_fajeilkadifej_jakdjfi.png

どんな助けでも大歓迎です。

他の情報:

モデル: ユーザー

Uploader: user_image (これは、フォルダー/ファイル名を格納する列名でもあります)

4

2 に答える 2

17

呼び出した後、モデルrecreate_versions!を呼び出す必要があります。誰かが基本的に同じことを尋ねたこの質問save!をチェックできます。

于 2013-06-25T14:14:04.407 に答える
9

README には、Carrierwave バージョンを再作成する方法が明確に記載されています。

https://github.com/jnicklas/carrierwave/blob/master/README.md

「バージョンをさかのぼって変更したり、新しいバージョンを追加したりしたい状況になるかもしれません。recreate_versions! メソッドを使用して、ベース ファイルからバージョンを再作成できます。これは、単純なアプローチを使用して、バージョンを再アップロードして処理します引数として何も渡されない場合は、指定されたバージョンまたはすべてのバージョン。

instance = MyUploader.new
instance.recreate_versions!(:thumb, :large)

または、マウントされたアップローダーで:

User.all.each do |user|
  user.avatar.recreate_versions!
end
于 2013-02-16T07:31:03.160 に答える