2012-01-16 2 views
4

大きなサイズのクリップ3Dイメージを新しい:urlおよび:path形式に移行するには、推奨される方法はありますか?ペーパークリップS3イメージを新しいURL /パスフォーマットに移行する

これは、rails 3.1にアップグレードした後、クロップ後に新しいバージョンのサムが表示されないためです(以前にキャッシュされたバージョンが表示されているため)。これは、ファイル名が変更されなくなった(asset_timestampがレール3.1で削除されたため)。私は使用しています:url/path形式のフィンガープリントですが、これはオリジナルから生成され、クロッピング時に変更されません。

url/path形式でupdated_atを挿入し、クロッピング中にattachment.updated_atを更新しようとしましたが、その変更を実装した後、既存のすべてのイメージを新しい場所に移動する必要があります。それは、S3上で名前を変更するために約50万枚の画像です。

この時点で、新しい場所にコピーしてから、コード変更を展開して見逃した画像(コピー後にアップロードされた画像)を移動することを検討していますが、もっと簡単な方法が必要です。 .. 助言がありますか?

答えて

2

新しいURL形式に移行するための実現可能な方法が見つかりませんでした。私はPaperclip::Attachment#generate_fingerprintを無効にしてしまい、:updated_atを追加しました。

5

画像クロッピングをサポートするためにクリップのパスを変更しなければならなかったので、私はrake taskを作成しました。

namespace :paperclip_migration do 

    desc 'Migrate data' 
    task :migrate_s3 => :environment do 
    # Make sure that all of the models have been loaded so any attachments are registered 
    puts 'Loading models...' 
    Dir[Rails.root.join('app', 'models', '**/*')].each { |file| File.basename(file, '.rb').camelize.constantize } 

    # Iterate through all of the registered attachments 
    puts 'Migrating attachments...' 
    attachment_registry.each_definition do |klass, name, options| 
     puts "Migrating #{klass}: #{name}" 
     klass.find_each(batch_size: 100) do |instance| 
     attachment = instance.send(name) 

     unless attachment.blank? 
      attachment.styles.each do |style_name, style| 
      old_path = interpolator.interpolate(old_path_option, attachment, style_name) 
      new_path = interpolator.interpolate(new_path_option, attachment, style_name) 
      # puts "#{style_name}:\n\told: #{old_path}\n\tnew: #{new_path}" 
      s3_copy(s3_bucket, old_path, new_path) 
      end 
     end 
     end 
    end 

    puts 'Completed migration.' 
    end 

    ############################################################################# 
    private 

    # Paperclip Configuration 
    def attachment_registry 
    Paperclip::AttachmentRegistry 
    end 

    def s3_bucket 
    ENV['S3_BUCKET'] 
    end 

    def old_path_option 
    ':class/:id_partition/:attachment/:hash.:extension' 
    end 

    def new_path_option 
    ':class/:attachment/:id_partition/:style/:filename' 
    end 

    def interpolator 
    Paperclip::Interpolations 
    end 

    # S3 
    def s3 
    AWS::S3.new(access_key_id: ENV['S3_KEY'], secret_access_key: ENV['S3_SECRET']) 
    end 

    def s3_copy(bucket, source, destination) 
    source_object = s3.buckets[bucket].objects[source] 
    destination_object = source_object.copy_to(destination, {metadata: source_object.metadata.to_h}) 
    destination_object.acl = source_object.acl 
    puts "Copied #{source}" 
    rescue Exception => e 
    puts "*Unable to copy #{source} - #{e.message}" 
    end 

end 
+0

ちょっと@jessecurry、これは動作することが証明されていますか?私の道は何ですか?それはまたDBを保存する? – Hamdan

+0

@その時私のために働いていたので、古いパスと新しいパスのオプションがあなたの設定に合っていることを確認する必要があります。 – jessecurry

関連する問題