2012-04-27 25 views
6

我想要在第二步中通过头像上传来构建3步用户注册。所以我按照Ryan Bates的指导http://railscasts.com/episodes/217-multistep-forms。我正在使用CarrierWave gem来处理上传。但似乎我不能在用户会话中存储上传的文件信息(我越来越无法转储文件错误)。我在控制器中使用以下技术与图像上传器的多步骤形式

它确实有帮助。但是,当我上载禁止的文件类型一切都崩溃在这条线

@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"] 

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

我该如何解决这个问题?谢谢 !

+0

你实际上传的是图片文件还是微软的word文件? – 2012-04-28 00:36:40

+0

我需要在上传之前验证文件类型 – AlphaB 2012-04-28 20:08:15

+0

您应该捕获CarrierWave :: IntegrityError或使用store()方法(不带!),因为它不会抛出错误。 – 2013-04-11 18:53:46

回答

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 
+0

恭喜修复!如果可以,请确保将您的答案标记为“已接受”,以便其他人能够从您的成功中学习。干杯〜 – 2012-04-28 20:17:03

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核心提取的一个提供数据库支持的会话存储(从而增加4kb会话限制)的gem。按照the documentation的安装说明,但在我的情况下,它是非常快速和无痛的设置,并忘记它。注意高流量用户:剩余会话记录似乎没有被gem清除,所以如果你获得足够的流量,这个表可能会膨胀到无数的行。

+0

我正面临同样的问题。解决方案简单谢谢 – Anwar 2017-09-17 18:57:10