I'm working on a rails app where the user will be uploading large quantities of images.
我正在开发一个rails应用程序,用户将上传大量图片。
My current setup: Using SWFUpload to upload multiple files at once using the Paperclip plugin with S3 storage. After the original image is uploaded to S3, Delayed_Job is used for the post processing (thumbnails, etc).
我目前的设置是:使用带有S3存储的Paperclip插件,使用SWFUpload一次性上传多个文件。将原始图像上传到S3后,Delayed_Job将用于后期处理(缩略图等)。
The problem I have is that the images upload at a very slow rate. I'm assuming the default Paperclip setup is that the image will go from the user to -> my server to -> s3.
我的问题是图像上传速度很慢。我假设默认的Paperclip设置是将图像从用户转到->我的服务器到-> s3。
I was thinking that I can have the images upload directly to s3 but I'm not sure how to implement that with Paperclip and post processing. I couldn't find any plugins or examples dealing with this.
我想我可以让图片直接上传到s3,但是我不知道如何使用Paperclip和post处理来实现。我找不到任何与此相关的插件或示例。
Does anyone have suggestions? If not, can you point me in the right direction?
谁有建议吗?如果没有,你能给我指出正确的方向吗?
Thanks in advance!
提前谢谢!
Tim
蒂姆
2 个解决方案
#1
3
I've ran into this same problem a few times. The way I solved it was by creating 2 models, a Image
model and a TempImage
model, which inherits from the Image
model. This requires you to have a type
column on your Image
table. The TempImage
model saves the image locally, then when you access it from the Image
model directly and resave it, it will follow whatever is defined in the Image
model, being Amazon S3.
我遇到过同样的问题好几次。我解决它的方法是创建两个模型,一个图像模型和一个TempImage模型,它继承了图像模型。这要求在映像表上有一个类型列。TempImage模型将图像保存在本地,然后当您从图像模型直接访问并重新保存它时,它将遵循图像模型中定义的任何内容,即Amazon S3。
Example:
例子:
# Will save in the database as a TempImage inside the Image table
temp = TempImage.create(:asset => File.new('some_path', 'r'))
# When you find it again through the Image model, it bypasses the type column
# so next time you save it, it is saved as an Image.
amazon = Image.find(temp.id)
amazon.save!
Here is my delayed job:
这是我被耽搁的工作:
class MoveToS3Job < Struct.new(:temp_revision_id)
def perform
upload = Image.find(temp_revision_id)
temp_path = File.expand_path("tmp/uploads/#{upload.asset_file_name}", Rails.root)
upload.asset = File.new(temp_path, 'r')
upload.save!
if File.exists?(temp_path) && !File.directory?(temp_path)
File.delete(temp_path)
end
rescue ActiveRecord::RecordNotFound
# If the record wasn't found, do some sort of
# error report, but don't keep it in the queue.
end
end
Here is the TempImage
model:
下面是TempImage模型:
class TempImage < Image
has_attached_file :asset, {
:path => ":rails_root/tmp/uploads/:basename_:updated_at.:extension"
}
end
Then the original Image
model:
然后原始图像模型:
class Image < ActiveRecord::Base
# Validations
validates :asset, :presence => true
# Paperclip
has_attached_file :asset, :styles => {
:preview => ['100x100#', :png],
:thumb => ['50x50#', :png]
},
:default_style => :thumb,
:storage => :s3,
:bucket => 'bucket-name',
:s3_credentials => File.expand_path('config/s3.yml', Rails.root),
:path => "photos/:id_partition/:style.:extension"
end
Your original Image
model should always contain your post processing, as that will be done in the background.
您的原始图像模型应该始终包含post处理,因为这将在后台完成。
You can always overwrite some methods to make it a little cleaner, but this gives you a better idea of how it works and what you need to do to so you can have it work like you want it to.
你总是可以重写一些方法使它更简洁,但是这会让你更好地了解它是如何工作的,以及你需要做什么,这样你就可以让它像你希望的那样工作。
#2
0
If you end up going the route of uploading directly to S3 which offloads the work from your Rails server, please check out my sample projects:
如果您最终采用直接上传至S3的方式,从您的Rails服务器上卸载工作,请查看我的示例项目:
Sample project using Rails 3, Flash and MooTools-based FancyUploader to upload directly to S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-FancyUploader
示例项目使用Rails3、Flash和基于mootools的FancyUploader直接上传到S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-FancyUploader。
Sample project using Rails 3, Flash/Silverlight/GoogleGears/BrowserPlus and jQuery-based Plupload to upload directly to S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-Plupload
示例项目使用Rails3、Flash/Silverlight/GoogleGears/BrowserPlus和基于jqueryplupload直接上传到S3: https://github.com/iwasrobbed/rails3 - uploader -Plupload
By the way, you can do post-processing with Paperclip using something like this blog post describes:
顺便说一下,你可以用Paperclip做后处理,使用类似的博客文章描述:
http://www.railstoolkit.com/posts/fancyupload-amazon-s3-uploader-with-paperclip
http://www.railstoolkit.com/posts/fancyupload-amazon-s3-uploader-with-paperclip
#1
3
I've ran into this same problem a few times. The way I solved it was by creating 2 models, a Image
model and a TempImage
model, which inherits from the Image
model. This requires you to have a type
column on your Image
table. The TempImage
model saves the image locally, then when you access it from the Image
model directly and resave it, it will follow whatever is defined in the Image
model, being Amazon S3.
我遇到过同样的问题好几次。我解决它的方法是创建两个模型,一个图像模型和一个TempImage模型,它继承了图像模型。这要求在映像表上有一个类型列。TempImage模型将图像保存在本地,然后当您从图像模型直接访问并重新保存它时,它将遵循图像模型中定义的任何内容,即Amazon S3。
Example:
例子:
# Will save in the database as a TempImage inside the Image table
temp = TempImage.create(:asset => File.new('some_path', 'r'))
# When you find it again through the Image model, it bypasses the type column
# so next time you save it, it is saved as an Image.
amazon = Image.find(temp.id)
amazon.save!
Here is my delayed job:
这是我被耽搁的工作:
class MoveToS3Job < Struct.new(:temp_revision_id)
def perform
upload = Image.find(temp_revision_id)
temp_path = File.expand_path("tmp/uploads/#{upload.asset_file_name}", Rails.root)
upload.asset = File.new(temp_path, 'r')
upload.save!
if File.exists?(temp_path) && !File.directory?(temp_path)
File.delete(temp_path)
end
rescue ActiveRecord::RecordNotFound
# If the record wasn't found, do some sort of
# error report, but don't keep it in the queue.
end
end
Here is the TempImage
model:
下面是TempImage模型:
class TempImage < Image
has_attached_file :asset, {
:path => ":rails_root/tmp/uploads/:basename_:updated_at.:extension"
}
end
Then the original Image
model:
然后原始图像模型:
class Image < ActiveRecord::Base
# Validations
validates :asset, :presence => true
# Paperclip
has_attached_file :asset, :styles => {
:preview => ['100x100#', :png],
:thumb => ['50x50#', :png]
},
:default_style => :thumb,
:storage => :s3,
:bucket => 'bucket-name',
:s3_credentials => File.expand_path('config/s3.yml', Rails.root),
:path => "photos/:id_partition/:style.:extension"
end
Your original Image
model should always contain your post processing, as that will be done in the background.
您的原始图像模型应该始终包含post处理,因为这将在后台完成。
You can always overwrite some methods to make it a little cleaner, but this gives you a better idea of how it works and what you need to do to so you can have it work like you want it to.
你总是可以重写一些方法使它更简洁,但是这会让你更好地了解它是如何工作的,以及你需要做什么,这样你就可以让它像你希望的那样工作。
#2
0
If you end up going the route of uploading directly to S3 which offloads the work from your Rails server, please check out my sample projects:
如果您最终采用直接上传至S3的方式,从您的Rails服务器上卸载工作,请查看我的示例项目:
Sample project using Rails 3, Flash and MooTools-based FancyUploader to upload directly to S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-FancyUploader
示例项目使用Rails3、Flash和基于mootools的FancyUploader直接上传到S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-FancyUploader。
Sample project using Rails 3, Flash/Silverlight/GoogleGears/BrowserPlus and jQuery-based Plupload to upload directly to S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-Plupload
示例项目使用Rails3、Flash/Silverlight/GoogleGears/BrowserPlus和基于jqueryplupload直接上传到S3: https://github.com/iwasrobbed/rails3 - uploader -Plupload
By the way, you can do post-processing with Paperclip using something like this blog post describes:
顺便说一下,你可以用Paperclip做后处理,使用类似的博客文章描述:
http://www.railstoolkit.com/posts/fancyupload-amazon-s3-uploader-with-paperclip
http://www.railstoolkit.com/posts/fancyupload-amazon-s3-uploader-with-paperclip