7

我想建立 3 步用户注册,并在第 2 步上传头像。所以我遵循 Ryan Bates 的指南http://railscasts.com/episodes/217-multistep-forms。我正在使用 CarrierWave gem 来处理上传。但似乎我无法在用户会话中存储上传的文件信息(我得到 can't dump File 错误)。我在控制器中使用以下技术

if params[:user][:img_path]
  @uploader = FirmImgUploader.new
  @uploader.store!(params[:user][:img_path])
  session[:img] = @uploader
  params[:user].delete(:img_path)
end

它实际上有帮助。但是当我上传禁止的文件类型时,这条线上的一切都崩溃了

@uploader.store!(params[:user][:img_path])

有这个错误

CarrierWave::IntegrityError in UsersController#create
You are not allowed to upload "docx" files, allowed types: ["jpg", "jpeg", "gif", "png"]

而不是正常的表单验证错误。

我怎么解决这个问题 ?谢谢 !

4

2 回答 2

3

其实我解决了我的问题。这是使用carrierwave上传文件的多步表单的工作代码

if params[:user][:img_path]
  @uploaded = params[:user][:img_path]
  params[:user].delete(:img_path)
end
session[:user_data].deep_merge!(params[:user]) if params[:user]
@user = User.new(session[:user_data])    

if @uploaded
  # here how validation will work
  @user.img_path = @uploaded
end
@user.current_stage = session[:register_stage]
if @user.valid?
  if @user.last_stage?
    @user.img_path  = session[:img] if @user.last_stage?
    @user.save
  else  
    @user.next_stage
  end
  # now we can store carrierwave object in session
  session[:img] = @user.img_path
  session[:register_stage] = @user.current_stage
end
于 2012-04-28T20:15:26.730 回答
1

这对于 OP 来说可能有点晚了,但希望这对某人有所帮助。我需要在用户会话中存储上传的图像(同样是多步骤表单),我也是从 Ryan 的Railscast #217开始的,但应用程序很快就超越了这一点。请注意,我的环境是 Ruby 2 上的 Rails 4,使用 Carrierwave 和 MiniMagick 以及activerecord-session_store,我将在下面解释。

我相信 OP 和我都遇到的问题是我们试图将所有 POST 参数添加到用户的会话中,但是通过文件上传,其中一个参数是实际的 UploadedFile 对象,这对于那个来说很大. 下面描述的方法是该问题的另一种解决方案。

免责声明:正如广泛指出的那样,在用户会话中存储复杂对象并不理想,最好存储记录标识符或其他标识符数据(例如图像的路径)并在需要时查找该数据。保持会话和模型/数据库数据同步(一项重要任务)的两个主要原因,以及默认的 Rails 会话存储(使用 cookie)限制为 4kb。

我的模型(submission.rb):

class Submission < ActiveRecord::Base
    mount_uploader :image_original, ImageUploader
    # ...
end

控制器(submissions_controller.rb):

def create
  # If the submission POST contains an image, set it as an instance variable, 
  # because we're going to remove it from the params
  if params[:submission] && params[:submission][:image_original] && !params[:submission][:image_original].is_a?(String)
    # Store the UploadedFile object as an instance variable
    @image = params[:submission][:image_original]
    # Remove the uploaded object from the submission POST params, since we 
    # don't want to merge the whole object into the user's session
    params[:submission].delete(:image_original)
  end

  # Merge existing session with POST params
  session[:submission_params].deep_merge!(params[:submission]) if params[:submission]

  # Instantiate model from newly merged session/params
  @submission = Submission.new(session[:submission_params])
  # Increment the current step in the session form
  @submission.current_step = session[:submission_step]

  # ... other steps in the form

  # After deep_merge, bring back the image
  if @image
    # This adds the image back to the Carrierwave mounted uploader (which 
    # re-runs any processing/versions specified in the uploader class):
    @submission.image_original = @image
    # The mounted uploader now has the image stored in the Carrierwave cache, 
    # and provides us with the cache identifier, which is what we will save 
    # in our session:
    session[:submission_params][:image_original] = @submission.image_original_cache
    session[:image_processed_cached] = @submission.image_original.url(:image_processed)
  end

  # ... other steps in the form

  # If we're on the last step of the form, fetch the image and save the model
  if @submission.last_step?
    # Re-populate the Carrierwave uploader's cache with the cache identifier 
    # saved in the session
    @submission.image_original_cache = session[:submission_params][:image_original]
    # Save the model
    @submission.save
    # ... render/redirect_to ...
  end
end

我的上传文件主要是一些自定义处理的库存。

注意:为了加强会话,我使用了 activerecord-session_store,它是从 v4 中的 Rails 核心提取的一个 gem,它提供了一个数据库支持的会话存储(从而增加了 4kb 的会话限制)。请按照文档获取安装说明,但在我的情况下,设置它并忘记它非常快速且轻松。高流量用户注意:剩余的会话记录似乎没有被 gem 清除,所以如果你获得足够的流量,这个表可能会膨胀到无数行。

于 2013-10-07T18:56:37.850 回答