回形针验证导致 Rails 3 出现错误

发布于 2024-11-29 16:58:03 字数 3008 浏览 1 评论 0原文

我最近在我的 Rails 3 应用程序中安装了回形针 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 btw):

= 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 protected]",
 "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

I've recently installed the paperclip gem to my Rails 3 app. I am trying to allow users to upload an avatar to their profile. I followed the install instructions and here is what my models/views look like:

My 'user.rb' model has the following code:

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']

I have added the following to the edit form html (I'm using HAML btw):

= 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

When I upload a picture (jpeg or png) that is under 1mb everything works smoothly; the image is uploaded, and there are no errors. If I try to upload any other type of file (MP3, txt, whatever) or the file/image is greater than 1mb rails gives me the following error:

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 protected]",
 "id"=>"6",
 "password"=>"[FILTERED]",
 "password_confirmation"=>"[FILTERED]"},
 "commit"=>"Save & Continue",
 "id"=>"2"}

I apologize if all of that was not required, but the error is a little non-descriptive, so I figured it's better to post in just in case.

I would like to know what I'm doing wrong with my validations that errors are not being generated, and the application is breaking. Any help on this matter would be greatly appreciated. I sincerely thank everyone who took the time to read this, and I kindly appreciate any help! Thanks!

UPDATE:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

開玄 2024-12-06 16:58:03

can't dump File 是 Ruby 在被要求使用 Marshal.dump 转储 File 对象时引发的错误。

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

所以问题可能出在验证失败时你做什么。如果您将 params(包含 File 对象)放入 sessionflash 对象中(这是由 Rails 转储的),这是你的问题。

can't dump File is the error Ruby raises when it is asked to dump a File object using Marshal.dump.

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

So the problem lies probably in what you do when the validation fails. If you're putting the params (which contains a File object) in the session or the flash objects (which are dumped by Rails), this is your problem.

梦里°也失望 2024-12-06 16:58:03

在我的例子中,问题是使用 清除回形针附件Attachment#clear 还不够,因为它仍然想保存一些文件

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

因此,以下两行解决了我的问题:

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

这是一个回形针错误,并在此提交。

The problem in my case that clearing out the paperclip attachment with Attachment#clear was not enough because it still wanted to save some File.

I've found out that the problem was with the @queued_for_write attribute in Attachment which still contained the data.

So the following two lines solved my problem:

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

This was a paperclip bug and was corrected in this commit.

黒涩兲箜 2024-12-06 16:58:03

是否尝试过?

@user.attachment.destroy

您在回复中分配 @user.errors 之前

Did you try

@user.attachment.destroy

before assigning @user.errors in your response?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文