Paperclip验证在Rails 3中导致错误

3

最近我在我的Rails 3应用程序中安装了paperclip gem。我试图允许用户上传他们的个人资料头像。我遵循了安装说明,这是我的模型/视图的样子:

我的“user.rb”模型有以下代码:

has_attached_file :avatar, 
                  :styles => { :small => "70x70>"},
                  :url  => "/users/:attachment/:id/:style/:basename.:extension",
                  :path => ":rails_root/public/users/:attachment/:id/:style/:basename.:extension"

validates_attachment_size :avatar, :less_than => 1.megabytes
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/png']

我已将以下内容添加到编辑表单html中(顺便说一下,我正在使用HAML):
= form_for (@user || User.new), :html => { :multipart => true } do |f|
...
.profile_picture.text_field
  = image_tag current_profile.avatar.url(:small)
  %br
  = f.file_field :avatar

当我上传一张大小不超过1MB的图片(jpeg或png格式)时,一切都很顺利;图片被成功上传,没有任何错误。但是如果我尝试上传其他类型的文件(如MP3、txt等),或者上传的文件/图片大小超过1MB,Rails会给出以下错误提示:

TypeError in UsersController#update

can't dump File

Request

Parameters:

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"LaiYjEEfgsE8JzzLsfkzk6TK8D4uxzIo5ASlu6ax2rY=",
 "user"=>{"avatar"=>#<ActionDispatch::Http::UploadedFile:0x000001053f0bf0 @original_filename="GT1_22HS_1_std.jpg",
 @content_type="image/jpeg",
 @headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"GT1_22HS_1_std.jpg\"\r\nContent-Type: image/jpeg\r\n",
 @tempfile=#<File:/var/folders/Ud/Udv4OlryEzWrHedR8pIe1E+++TI/-Tmp-/RackMultipart20110817-17075-1ikqcc0>>,
 "first_name"=>"First",
 "last_name"=>"Last",
 "country"=>"United States",
 "state"=>"California",
 "city"=>"City",
 "date_of_birth(1i)"=>"2011",
 "date_of_birth(2i)"=>"7",
 "date_of_birth(3i)"=>"12",
 "account_attributes"=>{"email"=>"email@email.com",
 "id"=>"6",
 "password"=>"[FILTERED]",
 "password_confirmation"=>"[FILTERED]"},
 "commit"=>"Save & Continue",
 "id"=>"2"}

如果我提供的信息过多,请谅解。由于错误提示不够清晰,所以我决定把所有信息都提供给您,以防万一。

我想知道我的验证出了什么问题,为什么没有生成错误信息,导致应用程序崩溃。非常感谢任何对此事提供帮助的人。我真诚地感谢每一个花时间阅读这篇文章的人,并非常感谢任何帮助!谢谢!

更新:

update method form user_controller.rb:

  def update
    session[:user_params] ||= {}
    session[:user_params].deep_merge!(params[:user]) if params[:user].present?

    @user.attributes = session[:user_params]

    respond_to do |format|
      if @user.save
        session[:user_params] = nil
        sign_in(@user.account, :bypass => true)
        format.html { redirect_to(root_url, :notice => 'User was successfully updated.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "edit", :layout => "userhome" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

它应该可以工作,你是否使用了最新版本的Paperclip?(目前为2.3.16) - Joost Baaij
是的,我是...有可能它在本地主机上不起作用,但一旦部署,它就会工作吗? - slovak_100
是的,这是可能的。如果您正在使用(内置的)WebRick服务器,则可能会意外截断较大的文件。尝试使用Passenger或Thin,看看是否有所帮助,因为这两个通常用于生产环境。要在开发中安装和使用Passenger:“gem install passenger”,然后“passenger start”。它将使用相同的http://localhost:3000/地址。 - Joost Baaij
似乎那并没有起作用...我部署了它,但如果上传的文件不符合验证规则,它仍然会显示错误。 - slovak_100
3个回答

2

无法转储文件是Ruby在使用Marshal.dump时被要求转储File对象时引发的错误。

Marshal.dump(File.new(".gemrc")) # => TypeError: can't dump File

所以问题可能在于当验证失败时你所做的事情。如果你将params(其中包含一个File对象)放入sessionflash对象中(这些对象是由Rails处理的),那么这就是问题所在。


我怀疑这可能是真的。我该如何检查是否将参数放在会话中?很抱歉,我知道这可能是一个非常基本的问题,但我对ror还很陌生,所以提前道歉。 - slovak_100
дҪ иғҪеҗҰеңЁдҪ зҡ„й—®йўҳдёӯж·»еҠ UsersControllerзҡ„updateж–№жі•зҡ„д»Јз Ғпјҹ - Michaël Witrant
@ Michael,非常感谢您迄今为止的帮助。对于我的回复迟了,我表示歉意。我附上了user_controller的更新方法,请告诉我是否需要其他任何信息。 - slovak_100
这个命令将文件放入会话中:session[:user_params].deep_merge!(params[:user])。如果模型有效,它将被重置,这就是为什么在这种情况下不会发生的原因。我不知道你为什么要进行此合并,但你应该避免这样做。 - Michaël Witrant

0

在我的情况下,仅清除带 Attachment#clear 的纸夹附件是不够的,因为它仍然想保存一些File

我发现问题出在 Attachment 中的 @queued_for_write 属性仍包含数据。

所以以下两行代码解决了我的问题:

unless @model.valid?
  @model.image.clear
  @model.image.queued_for_write.clear
end

这是一个纸夹错误,已在此提交中进行了更正。


-1

你尝试过吗?

@user.attachment.destroy

在响应中分配 @user.errors 之前?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接