2010-09-07 3 views
3

Я работаю над приложением rails, где пользователь будет загружать большое количество изображений.Скрепка для загрузки изображений на S3 в Rails. Загрузка файлов происходит очень медленно. Обход?

Моя текущая настройка: использование SWFUpload для загрузки нескольких файлов одновременно с помощью плагина Paperclip с хранилищем S3. После того, как исходное изображение загружено на S3, Delayed_Job используется для последующей обработки (миниатюры и т. Д.).

Проблема заключается в том, что загрузка изображений происходит очень медленно. Я предполагаю, что настройка Paperclip по умолчанию заключается в том, что изображение перейдет от пользователя к -> моему серверу -> s3.

Я думал, что я могу загрузить изображения непосредственно в s3, но я не уверен, как реализовать это с помощью Paperclip и последующей обработки. Я не мог найти никаких плагинов или примеров, связанных с этим.

У кого-нибудь есть предложения? Если нет, можете ли вы указать мне в правильном направлении?

Заранее благодарен!

Tim

ответ

3

Я столкнулся с этой проблемой несколько раз. То, как я решил это, было создание 2 моделей, модели Image и модели TempImage, которая наследуется от модели Image. Для этого вам необходимо иметь столбец type на вашем столе Image. Модель TempImage сохраняет изображение локально, а затем, когда вы напрямую обращаетесь к нему с модели Image и сохраняете ее, она будет следовать за тем, что определено в модели Image, являющейся Amazon S3.

Пример:

# 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! 

Вот моя задержка работы:

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 

Вот TempImage модель:

class TempImage < Image 
    has_attached_file :asset, { 
    :path => ":rails_root/tmp/uploads/:basename_:updated_at.:extension" 
    } 
end 

Тогда оригинальная Image модель:

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 

Ваша оригинальная модель Image всегда должна содержать вашу почтовую обработку, как это будет сделано в фоновом режиме.

Вы всегда можете переписать некоторые методы, чтобы сделать его немного более чистым, но это дает вам лучшее представление о том, как оно работает и что вам нужно сделать, чтобы вы могли работать так, как хотите.

0

Если вы в конечном итоге будет маршрут загрузки непосредственно на S3, которая разгружает работу с сервера Rails, пожалуйста, проверьте мои примеры проектов:

Пример проекта с использованием Rails 3, Flash и MooTools на основе FancyUploader для загрузки непосредственно S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-FancyUploader

Пример проекта с использованием Rails 3, Flash/Silverlight/GoogleGears/BrowserPlus и JQuery на основе Plupload для загрузки непосредственно на S3: https://github.com/iwasrobbed/Rails3-S3-Uploader-Plupload

Кстати, вы можете сделать пост-обработку с Скрепка используя что-то вроде этого сообщения в блоге d не указано:

http://www.railstoolkit.com/posts/fancyupload-amazon-s3-uploader-with-paperclip

Смежные вопросы