ファイルの添付や画像のサイズ変更などを処理するために、Paperclip を使用して Rails アプリを実行しています。このアプリは現在、EngineYard クラウドでホストされており、すべての添付ファイルは EBS に保存されています。すべての Paperclip 添付ファイルを処理するために S3 を使用することを考えています。
この移行のための適切で安全な方法を知っている人はいますか? どうもありがとう!
ファイルの添付や画像のサイズ変更などを処理するために、Paperclip を使用して Rails アプリを実行しています。このアプリは現在、EngineYard クラウドでホストされており、すべての添付ファイルは EBS に保存されています。すべての Paperclip 添付ファイルを処理するために S3 を使用することを考えています。
この移行のための適切で安全な方法を知っている人はいますか? どうもありがとう!
添付ファイルを繰り返し処理し、それぞれを S3 にプッシュする rake タスクを作成できます。これをしばらく前に attachment_fu で使用しましたが、それほど違いはありません。これは aws-s3 gem を使用します。
基本的なプロセスは次のとおりです。 1. 移動する必要があるファイルをデータベースから選択します。 2. それらを S3 にプッシュします。 3. データベースを更新して、ファイルがローカルに保存されなくなったことを反映します (この方法では、バッチで実行でき、同じファイルを 2 回プッシュすることを心配する必要があります)。
@attachments = Attachment.stored_locally
@attachments.each do |attachment|
base_path = RAILS_ROOT + '/public/assets/'
attachment_folder = ((attachment.respond_to?(:parent_id) && attachment.parent_id) || attachment.id).to_s
full_filename = File.join(base_path, ("%08d" % attachment_folder).scan(/..../), attachment.filename)
require 'aws/s3'
AWS::S3::Base.establish_connection!(
:access_key_id => S3_CONFIG[:access_key_id],
:secret_access_key => S3_CONFIG[:secret_access_key]
)
AWS::S3::S3Object.store(
'assets/' + attachment_folder + '/' + attachment.filename,
File.open(full_filename),
S3_CONFIG[:bucket_name],
:content_type => attachment.content_type,
:access => :private
)
if AWS::S3::Service.response.success?
# Update the database
attachment.update_attribute(:stored_on_s3, true)
# Remove the file on the local filesystem
FileUtils.rm full_filename
# Remove directory also if it is now empty
Dir.rmdir(File.dirname(full_filename)) if (Dir.entries(File.dirname(full_filename))-['.','..']).empty?
else
puts "There was a problem uploading " + full_filename
end
end
私は同じ状況に陥り、bensie のコードを取得して自分で動作させるようにしました - これが私が思いついたものです:
require 'aws/s3'
# Ensure you do the following:
# export AMAZON_ACCESS_KEY_ID='your-access-key'
# export AMAZON_SECRET_ACCESS_KEY='your-secret-word-thingy'
AWS::S3::Base.establish_connection!
@failed = []
@attachments = Asset.all # Asset paperclip attachment is: has_attached_file :attachment....
@attachments.each do |asset|
begin
puts "Processing #{asset.id}"
base_path = RAILS_ROOT + '/public/'
attachment_folder = ((asset.respond_to?(:parent_id) && asset.parent_id) || asset.id).to_s
styles = asset.attachment.styles.keys
styles << :original
styles.each do |style|
full_filename = File.join(base_path, asset.attachment.url(style, false))
AWS::S3::S3Object.store(
'attachments/' + attachment_folder + '/' + style.to_s + "/" + asset.attachment_file_name,
File.open(full_filename),
"swellnet-assets",
:content_type => asset.attachment_content_type,
:access => (style == :original ? :private : :public_read)
)
if AWS::S3::Service.response.success?
puts "Stored #{asset.id}[#{style.to_s}] on S3..."
else
puts "There was a problem uploading " + full_filename
end
end
rescue
puts "Error with #{asset.id}"
@failed << asset.id
end
end
puts "Failed uploads: #{@failed.join(", ")}" unless @failed.empty?
もちろん、複数のモデルがある場合は、必要に応じて調整する必要があります...