好吧,所以我弄清楚如何做到這一點,我會在下面解釋。我的預感是正確的,使用兩個不同的CarrierWave上傳類 - 一類專用於上傳到S3(使用CarrierWave_Direct gem),另一類僅用於圖像處理(我已經在生產中使用類)。我會嘗試發佈下面的相關代碼,但如果任何人有問題讓我知道。我不確定爲什麼我沒有看到別人使用這樣的單獨的類,但它似乎爲我工作。利用carrierwave_direct寶石
我的圖片上傳類app\uploaders\image_uploader.rb
:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
include ActiveModel::Conversion
extend ActiveModel::Naming
include CarrierWave::MimeTypes
process :set_content_type
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Override the directory where uploaded files will be stored.
# CarrierWaveDirect::Uploader puts raw uploaded files in this directory on S3 as a first step
def store_dir
"unprocessed_uploads"
end
end
**注意有沒有在這個類
我的圖像處理類app\uploaders\image_processor.rb
(什麼是已經在生產的地方)正在做處理:
class ImageProcessor < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
include CarrierWave::MimeTypes
process :set_content_type
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
# "uploads/#{model.class.to_s.underscore}/path/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
"logos/" + [version_name, "default.png"].compact.join('_')
end
# Process files fetched from S3 after they are uploaded:
def make_thumbnail(width, height)
# uses MiniMagick classes to get a square, centered thumbnail image
manipulate! do |img|
if img[:width] < img[:height]
remove = ((img[:height] - img[:width])/2).round
img.shave("0x#{remove}")
elsif img[:width] > img[:height]
remove = ((img[:width] - img[:height])/2).round
img.shave("#{remove}x0")
end
img.resize("#{width}x#{height}")
img
end
end
# Create different versions of your uploaded files:
# the process statement below isn't defined within a version block on purpose--this means the ORIGINAL uploaded photo is constrained to 1050 pics
process :resize_to_limit => [1050, 1050]
process :quality => 85 # this reduces filesize greatly and saves space
version :thumb do
process :make_thumbnail => [100, 100]
process :quality => 85 # this reduces filesize greatly and saves space
end
version :big_thumb do
process :make_thumbnail => [350, 350]
process :quality => 85 # this reduces filesize greatly and saves space
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
if original_filename
if model && model.read_attribute(:image).present?
model.read_attribute(:image)
else
"#{secure_token}.#{file.extension}"
end
end
end
protected
def secure_token
var = :"@#{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end
end
我的照片模式(總結):
class Photo < ActiveRecord::Base
mount_uploader :image, ImageProcessor
def save_and_process_image(options = {})
s3_unprocessed_image_url = self.image.asset_host + '/' + self.key
# this next line downloads the image from S3
# and this save line below will process the image and reupload to S3 according to ImageProcessor settings
self.remote_image_url = s3_unprocessed_image_url
save
end
end
我也有照片控制器和視圖代碼可用,如果你想它讓我知道。基本上我使用ImageUploader類來執行到S3的初始上傳到名爲unprocessed_uploads的文件夾。然後S3迴應URL中的key
字段,我將這個字段傳遞給ImageProcessor類 - 它附加到Photo上並處理縮略圖和其他圖像,然後將它們重新上傳到S3上我上傳的文件夾中。
這種分離意味着在添加carrierwave_direct gem時,我不需要在S3上更改當前的文件夾結構。希望這有助於他人。讓我知道如果你需要更多的代碼,我有點累了打字:)
UPDATE的 - 添加更多的代碼:
照片控制器:
class PhotosController < ApplicationController
def index
@photos = @photos.sort_by(&:created_at)
@uploader = ImageUploader.new
@uploader.success_action_redirect = new_tank_photo_url(@tank)
respond_to do |format|
format.html # index.html.erb
format.json { render json: @photos }
end
end
def create
respond_to do |format|
if @photo.save_and_process_image
format.html { redirect_to tank_photos_path(@tank), notice: 'Photo uploaded successfully and is being processed...' }
format.json { render json: @photo, status: :created, location: @photo }
else
format.html { render :new }
format.json { render json: @photo.errors, status: :unprocessable_entity }
end
end
end
照片索引視圖,上傳按鈕的形式:
<%= direct_upload_form_for @uploader, :html => {:class => "form-inline"} do |f| %>
<%= f.file_field :image %>
<%= f.submit "Upload", :class => "btn btn-primary btn-medium" %>
<% end %>
因此,添加上述視圖/控制器代碼,他re是所採取措施的總結。請注意0類和ImageProcessor
類之間的差別:
- 在我的照片控制器I創建@uploader變量,它是類ImageUploader的 - 這意味着,在使用我的索引/視圖的形式提交的圖片@上傳器會將圖像上傳到「臨時」文件夾 - 由於此操作使用ImageUploader類,因此在此圖像上傳(尚未)時不會執行任何處理。
- 當用戶單擊表單上的「上傳」按鈕時,將調用照片>>創建操作。此操作調用@ photo.save_and_process_image - 查看模型,以查看該方法實際上是從S3'temp'文件夾中抓取最近上傳的圖像,對其進行處理,然後將處理後的圖像重新上傳到最終目的地。這一切都是可能的,因爲我的照片模型鏈接到ImageProcessor類,它處理/上傳。它沒有鏈接到單獨的ImageUploader類。
希望這有助於解釋我對
我這裏有同樣的問題去,好像CW_direct,打破store_dir! 那麼,我想知道如果控制器和視圖是一樣的ryan bate在http://railscasts.com/episodes/383-uploading-to-amazon-s3解釋。 感謝的 – dcalixto 2013-06-24 11:26:18
@dcalixto,不,我不得不從這個railscast事件中脫身。我會說我起初有點害怕失敗,但這對我來說並不合適。我使用這個插曲來更好地理解CW和S3,然後必須將我的代碼更改爲上面的2步處理,以解決CW打破store_dir的問題。讓我知道如何去審查上面更新的代碼。祝你好運! – FireDragon 2013-06-26 20:04:32
非常感謝。太糟糕了,從carrierwave升級沒有更容易的向後兼容的方法。你不必在你的Uploader類中重寫store_dir,對嗎?默認的地方很好,因爲你總是可以使用#direct_fog_url – sfkaos 2014-09-19 20:48:19