开发者

Adding :multipart => true throws Undefined Method "name" error

I'm drawing a blank on this one. Here's my problem:

Short Version

My image#create action is failing on the image.save call and throwing Undefined method "name" for nil:NilClass. The Image model includes a file upload via paperclip gem.

The part that is throwing me:

the error only occurs when I include :multipart => true on the submitting form

When I take that out, the form works perfectly, except of course the image file doesn't get uploaded. See the stack trace below for details on where it fails. It looks like its hitting a nil value when trying to quote something for the INSERT statement, but I can't figure out what. My controller parameters look ok, and I checked via the logger to make sure the new Image instance is properly built just before it hits the save call.

Extra Details

I'll try to include all the details I can think of, ordered by importance:

  • I'm using paperclip and attempting to store via S3, although this problem still occurs when I completely comment out the has_attached_file line in my Image model.

  • Image is a nested resource inside Collection, which is referenced by a slug in its to_param method.

  • I have the basics of a multi-tenant system (aka Basecamp-style user subdomains, implemented via a central user model that scopes all the components).

Parameters passed to controller

{"utf8"=>"✓",
 "authenticity_token"=>"JYCMky7851j5cW4ChSWUCCL/02iePf6i/QWAgR8q5tE=",
 "image"=>{"name"=>"My testerific image 2",
 "slug"=>"my-testerific-image-2",
 "description"=>"w",
 "collection_id"=>"2",
 "sort"=>"3",
 "picture_file_name"=>#<ActionDispatch::Http::UploadedFile:0x00000101b3f540 @original_filename="David's pic 005.jpeg",
 @content_type="image/jpeg",
 @headers="Content-Disposition: form-data; name=\"image[picture_file_name]\"; filename=\"David's pic 005.jpeg\"\r\nContent-Type: image/jpeg\r\n",
 @tempfile=#<File:/var/folders/df/mvsv5cs137gbyl8r7h428zp40000gn/T/RackMultipart20110814-64770-duz6wu>>},
 "commit"=>"Create Image",
 "collection_id"=>"my-new-collection"}

Full stack trace

activesupport (3.0.9) lib/active_support/whiny_nil.rb:48:in 'method_missing'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:20:in 'block in initialize'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'yield'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'default'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'block in initialize'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'yield'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'default'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'block in initialize'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'yield'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'default'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'block in initialize'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'yield'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'default'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:22:in 'block in initialize'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:63:in 'yield'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:63:in 'default'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:63:in 'accept'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:325:in 'block in dump_ivars'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:323:in 'each'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:323:in 'dump_ivars'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:85:in 'visit_Object'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:63:in 'accept'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:36:in '<<'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych.rb:165:in 'dump'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/core_ext.rb:13:in 'psych_to_yaml'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/quoting.rb:34:in 'quote'
activerecord (3.0.9) lib/active_record/connection_adapters/sqlite3_adapter.rb:45:in 'quote'
arel (2.0.10) lib/arel/visitors/to_sql.rb:327:in 'quote'
arel (2.0.10) lib/arel/visitors/to_sql.rb:70:in 'block in visit_Arel_Nodes_Values'
arel (2.0.10) lib/arel/visitors/to_sql.rb:69:in 'map'
arel (2.0.10) lib/arel/visitors/to_sql.rb:69:in 'visit_Arel_Nodes_Values'
arel (2.0.10) lib/arel/visitors/visitor.rb:15:in 'visit'
arel (2.0.10) lib/arel/visitors/to_sql.rb:59:in 'visit_Arel_Nodes_InsertStatement'
arel (2.0.10) lib/arel/visitors/visitor.rb:15:in 'visit'
arel (2.0.10) lib/arel/visitors/visitor.rb:5:in 'accept'
arel (2.0.10) lib/arel/visitors/to_sql.rb:18:in 'block in accept'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/connection_pool.rb:111:in 'with_connection'
arel (2.0.10) lib/arel/visitors/to_sql.rb:16:in 'accept'
arel (2.0.10) lib/arel/tree_manager.rb:20:in 'to_sql'
arel (2.0.10) lib/arel/select_manager.rb:217:in 'insert'
activerecord (3.0.9) lib/active_record/relation.rb:14:in 'insert'
activerecord (3.0.9) lib/active_record/persistence.rb:274:in 'create'
activerecord (3.0.9) lib/active_record/timestamp.rb:47:in 'create'
activerecord (3.0.9) lib/active_record/callbacks.rb:277:in 'block in create'
activesupport (3.0.9) lib/active_support/callbacks.rb:414:in '_run_create_callbacks'
activerecord (3.0.9) lib/active_record/callbacks.rb:277:in 'create'
activerecord (3.0.9) lib/active_record/persistence.rb:250:in 'create_or_update'
activerecord (3.0.9) lib/active_record/callbacks.rb:273:in 'block in create_or_update'
activesupport (3.0.9) lib/active_support/callbacks.rb:429:in '_run_save_callbacks'
activerecord (3.0.9) lib/active_record/callbacks.rb:273:in 'create_or_update'
activerecord (3.0.9) lib/active_record/persistence.rb:40:in 'save'
activerecord (3.0.9) lib/active_record/validations.rb:43:in 'save'
activerecord (3.0.9) lib/active_record/attribute_methods/dirty.rb:21:in 'save'
activerecord (3.0.9) lib/active_record/transactions.rb:240:in 'block (2 levels) in save'
activerecord (3.0.9) lib/active_record/transactions.rb:292:in 'block in with_transaction_returning_status'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/database_statements.rb:139:in 'transaction'
activerecord (3.0.9) lib/active_record/transactions.rb:207:in 'transaction'
activerecord (3.0.9) lib/active_record/transactions.rb:290:in 'with_transaction_returning_status'
activerecord (3.0.9) lib/active_record/transactions.rb:240:in 'block in save'
activerecord (3.0.9) lib/active_record/transactions.rb:251:in 'rollback_active_record_state!'
activerecord (3.0.9) lib/active_record/transactions.rb:239:in 'save'
app/controllers/images_controller.rb:42:in 'block in create'
actionpack (3.0.9) lib/action_controller/metal/mime_responds.rb:264:in 'call'
actionpack (3.0.9) lib/action_controller/metal/mime_responds.rb:264:in 'retrieve_response_from_mimes'
actionpack (3.0.9) lib/action_controller/metal/mime_responds.rb:191:in 'respond_to'
app/controllers/images_controller.rb:40:in 'create'
actionpack (3.0.9) lib/action_controller/metal/implicit_render.rb:4:in 'send_action'
actionpack (3.0.9) lib/abstract_controller/base.rb:150:in 'process_action'
actionpack (3.0.9) lib/action_controller/metal/rendering.rb:11:in 'process_action'
actionpack (3.0.9) lib/abstract_controller/callbacks.rb:18:in 'block in process_action'
activesupport (3.0.9) lib/active_support/callbacks.rb:451:in '_run__867212960703161301__process_action__2360218484576085785__callbacks'
activesupport (3.0.9) lib/active_support/callbacks.rb:410:in '_run_process_action_callbacks'
activesupport (3.0.9) lib/active_support/callbacks.rb:94:in 'run_callbacks'
actionpack (3.0.9) lib/abstract_controller/callbacks.rb:17:in 'process_action'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:30:in 'block in process_action'
activesupport (3.0.9) lib/active_support/notifications.rb:52:in 'block in instrument'
activesupport (3.0.9) lib/active_support/notifications/instrumenter.rb:21:in 'instrument'
activesupport (3.0.9) lib/active_support/notifications.rb:52:in 'instrument'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:29:in 'process_action'
actionpack (3.0.9) lib/action_controller/metal/rescue.rb:17:in 'process_action'
actionpack (3.0.9) lib/abstract_controller/base.rb:119:in 'process'
actionpack (3.0.9) lib/abstract_controller/rendering.rb:41:in 'process'
actionpack (3.0.9) lib/action_controller/metal.rb:138:in 'dispatch'
actionpack (3.0.9) lib/action_controller/metal/rack_delegation.rb:14:in 'dispatch'
actionpack (3.0.9) lib/action_controller/metal.rb:178:in 'block in action'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:62:in 'call'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:62:in 'dispatch'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:27:in 'call'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in 'block in call'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in 'block in recognize'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:68:in 'optimized_each'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in 'recognize'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in 'call'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:493:in 'call'
warden (1.0.5) lib/warden/manager.rb:35:in 'block in call'
warden (1.0.5) lib/warden/manager.rb:34:in 'catch'
warden (1.0.5) lib/warden/manager.rb:34:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/best_standards_support.rb:17:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/head.rb:14:in 'call'
rack (1.2.3) lib/rack/methodoverride.rb:24:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/params_parser.rb:21:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/flash.rb:182:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/session/abstract_store.rb:149:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/cookies.rb:302:in 'call'
activerecord (3.0.9) lib/active_record/query_cache.rb:32:in 'block in call'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in 'cache'
activerecord (3.0.9) lib/active_record/query_cache.rb:12:in 'cache'
activerecord (3.0.9) lib/active_record/query_cache.rb:31:in 'call'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/connection_pool.rb:354:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/callbacks.rb:46:in 'block in call'
activesupport (3.0.9) lib/active_support/callbacks.rb:416:in '_run_call_callbacks'
actionpack (3.0.9) lib/action_dispatch/middleware/callbacks.rb:44:in 'call'
rack (1.2.3) lib/rack/sendfile.rb:107:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/remote_ip.rb:48:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/show_exceptions.rb:47:in 'call'
railties (3.0.9) lib/rails/rack/logger.rb:13:in 'call'
rack (1.2.3) lib/rack/runtime.rb:17:in 'call'
activesupport (3.0.9) lib/active_support/cache/strategy/local_cache.rb:72:in 'call'
rack (1.2.3) lib/rack/lock.rb:11:in 'block in call'
<internal:prelude>:10:in 'synchronize'
rack (1.2.3) lib/rack/lock.rb:11:in 'call'
actionpack (3.0.9) lib/action_dispatch/middleware/static.rb:30:in 'call'
railties (3.0.9) lib/rails/application.rb:168:in 'call'
railties (3.0.9) lib/rails/application.rb:77:in 'method_missing'
railties (3.0.9) lib/rails/rack/log_tailer.rb:14:in 'call'
rack (1.2.3) lib/rack/content_length.rb:13:in 'call'
rack (1.2.3) lib/rack/handler/webrick.rb:52:in 'service'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:111:in 'service'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:70:in 'run'
/Users/daw/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/server.rb:183:in 'block in start_thread'

Update

As requested, model code:

class Image < ActiveRecord::Base
  belongs_to :collection
  belongs_to :user

  before_save :create_slug

  has_attached_file :picture,
    #:styles => { 
        #   :thumb => '100x100>', 
        #   :full => '800x800>' 
        #},
        :storage => :s3,
        :s3_credentials => Rails.root.join( 'config', 's3.yml' ),
        :path => ":id/:style/:filename"


  def to_param
    self.name.parameterize
  end
  private
  def create_slug
    self.slug = self.to_param
  end
end

Update 2

I compared the Image instance that was built with :multipart => true vs without it, and confirmed the only difference is the file upload field, picture_file_name. Without :multipart => true, it a string with the filename (not surprising). With it, it is an instance of ActionDispatch::Http::UploadedFile. Given that the stack trace shows its failing during a to_yaml call, perhaps the problem lies with the UploadedF开发者_如何学运维ile instance converting to YAML?


Well, I finally buckled down and traced my way through the ActiveRecord source code via logger outputs. Turns out, as I suspected, it was failing to save the UploadedFile because it couldn't convert it to YAML.

However, this because of a stupid mistake on my part. In my submitting form, I had:

<%= f.file_field :picture_file_name %>

When it should have been:

<%= f.file_field :picture %>

The paperclip gem understands that :picture is the uploaded file and works the background magic to save the file name to the proper field. I just underestimated the ease of use I guess!

Normally, I would delete the question for something this trivial, but seeing as I made this mistake, others probably will in the future, and there was very little out there to point me to the solution. So I will keep it up to aid in the future googling of similarly dense developers!


After lot of searching and debugging. The main symptom of this problem is that form with a file field are being made as multipart form and rails 3.2 is not able to save the data because it is trying to save other parameters that are not present in your database (The filed for the file object).

Taking the appopriate values and saving them to some variable and removing the file hash from the params has seems to work around the issue!

Here is an example of a working code to save in the database using rails 3.2

file = params[:document][:file].tempfile.read
params[:document].delete(:file)
@document = Document.new(params[:document])   
respond_to do |format|
  if @document.save
@document.file = file
@document.save
    format.html { redirect_to @document, notice: 'Document was successfully created.' }
    format.json { render json: @document, status: :created, location: @document }
  else
    format.html { render action: "new" }
    format.json { render json: @document.errors, status: :unprocessable_entity }
  end
end


You didn't post it, but I think you should go with :html => { :multipart => true } instead of just :multipart => true in your form, like:

form_for object, :html => { :multipart => true } do |o|
    ...


I had spent about a week on the same error, even though I had the correct fields.

The silliness causing all my headaches was simply the order of tags in the view.

Caused Error

NoMethodError in DatenightsController#create undefined methodname' for nil:NilClass:

<%= f.file_field :photo %>
<%= f.text_field :name %>

Solution for above quoted Error (Just the sequence/order matters a lot here)

<%= f.text_field :name %>
<%= f.file_field :photo %>

Since the issue took so much of my sweet time I thought it may help you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜