这可能是有点晚了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核心提取的一个提供数据库支持的会话存储(从而增加4kb会话限制)的gem。按照the documentation的安装说明,但在我的情况下,它是非常快速和无痛的设置,并忘记它。注意高流量用户:剩余会话记录似乎没有被gem清除,所以如果你获得足够的流量,这个表可能会膨胀到无数的行。
你实际上传的是图片文件还是微软的word文件? – 2012-04-28 00:36:40
我需要在上传之前验证文件类型 – AlphaB 2012-04-28 20:08:15
您应该捕获CarrierWave :: IntegrityError或使用store()方法(不带!),因为它不会抛出错误。 – 2013-04-11 18:53:46