Ruby on rails CarrierWave_Direct gem:在S3上保持当前目录结构

Ruby on rails CarrierWave_Direct gem:在S3上保持当前目录结构,ruby-on-rails,image,amazon-s3,carrierwave,Ruby On Rails,Image,Amazon S3,Carrierwave,因此,我有一个网站已经在生产中使用carrierwave gem,图像存储在AmazonS3上。我的上传程序使用store\u dir方法指定一个特定的结构以放入处理过的图像 现在,在我的开发环境中,我添加了carrierwave_direct gem,开始直接上传到S3。问题是这个gem完全覆盖了我的上传程序中的store_dir和filename默认值。我不能推动我的全部工作上传现场,因为我所有的旧图像链接将被打破 据我所知,CWdirect gem会将一个原始图像文件上传到S3上的“tem

因此,我有一个网站已经在生产中使用carrierwave gem,图像存储在AmazonS3上。我的上传程序使用
store\u dir
方法指定一个特定的结构以放入处理过的图像

现在,在我的开发环境中,我添加了carrierwave_direct gem,开始直接上传到S3。问题是这个gem完全覆盖了我的上传程序中的store_dir和filename默认值。我不能推动我的全部工作上传现场,因为我所有的旧图像链接将被打破

据我所知,CWdirect gem会将一个原始图像文件上传到S3上的“temp”目录,然后S3响应并给您一个
变量,这样您就可以抓取该文件并根据需要处理它。那么,我是否应该在carrierwave中使用一个完全独立的图像上传器类来处理图像并将其放置在正确的文件夹中?这意味着我将有一个上传器专门用于carrierwave_direct,它可以上传这个gem想要上传到的任何地方;我将使用另一个uploader.rb类链接到我的真实模型,它保持我当前的存储目录和文件名结构


在任何情况下,我的基本问题是,如果我已经在生产中运行CW,并且图像位于特定的文件夹结构中,如何使用CarrierWave_Direct gem

好的,我确实想好了怎么做,下面我会解释。我的直觉是正确的,使用了两个不同的CarrierWave上传器类——一个专用于上传到S3的类(使用CarrierWave_Direct gem),另一个类仅用于图像处理(我已经在生产中使用过的类)。我将尝试在下面发布相关代码,但如果有人有问题,请告诉我。我不确定为什么我没有看到其他人像这样使用单独的类,但它似乎对我有用

我的图像上传器类
app\uploaders\image\u 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
我的照片模型(摘要):

照片索引视图,带有上载按钮的表单:

    <%= 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 %>
{:class=>“表单内联”}do | f |%>
“btn btn主btn媒体”%>
因此,添加了上述视图/控制器代码后,下面是所采取步骤的摘要。请注意
ImageUploader
类和
ImageProcessor
类之间的区别:

  • 在我的照片控制器中,我创建了@uploader变量,它属于ImageUploader类——这意味着在使用@uploader的索引/视图表单中提交的图像将上载到“temp”文件夹——因为它使用ImageUploader类,所以上载该图像时不会进行任何处理(尚未)
  • 当用户单击表单上的“上载”按钮时,将调用照片>>创建操作。此操作调用@photo.save_和_process_image——查看模型,查看此方法是否实际从S3'temp'文件夹中获取最近上载的图像,对其进行处理,然后将处理后的图像重新上载到最终目的地。这一切都是可能的,因为我的照片模型链接到ImageProcessor类,该类负责处理/上传。它没有链接到单独的ImageUploader类

  • 希望这有助于解释我在做什么

    我这里也有同样的问题,好像是CW_direct,break the store_dir!我想知道控制器和视图是否与ryan bate在上解释的相同。谢谢s@dcalixto不,我不得不从这段铁路史上的插曲中解脱出来。我会说,一开始我有点害怕脱离,但这对我来说根本不起作用。我用这一集来更好地理解CW和S3,然后不得不将代码更改为上面的两步过程,以克服CW破坏存储目录的问题。让我知道事情进展如何,并查看上面更新的代码。祝你好运谢谢你。遗憾的是,没有一种更容易的向后兼容的方式从carrierwave升级。您不必在Uploader类中重写store_dir,对吗?默认位置很好,因为您始终可以使用#direct#u fog获取URL_url@sfkaos我已经有一段时间没有看过这段代码了,但实际上S3上有两个完全独立的上传目录。因此,我相信您可以选择覆盖Uploader类,或者不覆盖Uploader类,因为它完全独立于最终目标文件夹,而最终目标文件夹是在Processor类中指定的。
    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
    
    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 %>