4

S3 に写真をアップロードするために、3 つの別々のモデルで Carrierwave を使用しています。ルート S3 バケットに写真を保存するアップローダのデフォルト設定を維持しました。次に、アップロード元のモデルに基づいて、/avatars、items/ などのモデル名に従ってサブディレクトリに保存することにしました...

その後、同じ名前のファイルが上書きされていて、モデル レコードを削除したときに写真が削除されていないことに気付きました。

それ以来、次のようなアップローダー固有の設定から store_dir を変更しました。

  def store_dir
    "items"
  end

モデルIDの下に写真を保存する一般的なものに(私はmongo FYIを使用しています):

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

ここで問題が発生します。すでに S3 にあるすべての写真を S3 内の適切な「ディレクトリ」に移動しようとしています。私が準備したものから、S3にはディレクトリ自体がありません。レーキタスクに問題があります。store_dir を変更したため、Carrierwave は以前に間違ったディレクトリにアップロードされたすべての写真を探しています。

namespace :pics do
  desc "Fix directory location of pictures on s3"
  task :item_update => :environment do
    connection = Fog::Storage.new({
      :provider                 => 'AWS',
      :aws_access_key_id => 'XXXX',
      :aws_secret_access_key => 'XXX'
    })
    directory = connection.directories.get("myapp-uploads-dev")

    Recipe.all.each do |l|
      if l.images.count > 0
        l.items.each do |i|
          if i.picture.path.to_s != ""
            new_full_path = i.picture.path.to_s
            filename = new_full_path.split('/')[-1].split('?')[0]
            thumb_filename = "thumb_#{filename}"
            original_file_path = "items/#{filename}"
            puts "attempting to retrieve: #{original_file_path}"
            original_thumb_file_path = "items/#{thumb_filename}"
            photo = directory.files.get(original_file_path) rescue nil
            if photo
              puts "we found: #{original_file_path}"
              photo.expires = 2.years.from_now.httpdate
              photo.key = new_full_path
              photo.save
              thumb_photo = directory.files.get(original_thumb_file_path) rescue nil
              if thumb_photo
                puts "we found: #{original_thumb_file_path}"
                thumb_photo.expires = 2.years.from_now.httpdate
                thumb_photo.key = "/uploads/item/picture/#{i.id}/#{thumb_filename}"
                thumb_photo.save
              end
            end
          end
        end
      end
    end
  end
end

そのため、すべてのレシピをループして、写真付きのアイテムを探し、古い Carrierwave パスを特定し、store_dir の変更に基づいて新しいパスで更新しようとしています。photo.key を新しいパスで単純に更新すればうまくいくと思いましたが、そうではありません。

私は何を間違っていますか?ここで質問を達成するためのより良い方法はありますか?

これを機能させるために私がしたことは次のとおりです...

namespace :pics do
  desc "Fix directory location of pictures"
  task :item_update => :environment do
    connection = Fog::Storage.new({
      :provider                 => 'AWS',
      :aws_access_key_id => 'XXX',
      :aws_secret_access_key => 'XXX'
    })
    bucket = "myapp-uploads-dev"
    puts "Using bucket: #{bucket}"
    Recipe.all.each do |l|
      if l.images.count > 0
        l.items.each do |i|
          if i.picture.path.to_s != ""
            new_full_path = i.picture.path.to_s
            filename = new_full_path.split('/')[-1].split('?')[0]
            thumb_filename = "thumb_#{filename}"
            original_file_path = "items/#{filename}"
            original_thumb_file_path = "items/#{thumb_filename}"
            puts "attempting to retrieve: #{original_file_path}"
            # copy original item
            begin
              connection.copy_object(bucket, original_file_path, bucket, new_full_path, 'x-amz-acl' => 'public-read')
              puts "we just copied: #{original_file_path}"
            rescue
              puts "couldn't find: #{original_file_path}"
            end
            # copy thumb
            begin
              connection.copy_object(bucket, original_thumb_file_path, bucket, "uploads/item/picture/#{i.id}/#{thumb_filename}", 'x-amz-acl' => 'public-read')
              puts "we just copied: #{original_thumb_file_path}"
            rescue
              puts "couldn't find thumb: #{original_thumb_file_path}"
            end

          end
        end
      end
    end
  end
end

おそらく世界で最も美しいものではありませんが、うまくいきました.

4

1 に答える 1