1

I've two models with a polymorphic association (hopefully set up well). When I try to upload a file I run in an error witch tells me something like: NoMethodError: undefined method `name' for nil:NilClass: INSERT INTO "uploads" I have absolut no glue where the name attribute comes from and why the model saves if I left the file attribute empty.

class Event < ActiveRecord::Base
  attr_accessible :title,
    :uploads_attributes

  has_many :uploads, :as => :uploadable
  accepts_nested_attributes_for :uploads
end

class Upload < ActiveRecord::Base
  attr_accessible :filename, :path, :title

  belongs_to :uploadable, :polymorphic => true
end

Here the form views for adding new events with uploads

<%= form_for(@event) do |f| %>
  <div class="field">
    <%= f.text_area :title, :rows => 4 %>
  </div>
  <div>
    <%= f.fields_for :uploads do |builder| %>
      <div><%= builder.text_field :title %></div>
      <div><%= builder.file_field :filename %></div>
    <% end %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

The controller is straight forward like shown in Railscast episodes #196 and #197

def new
  @event = Event.new
  @event.uploads.build

  respond_to do |format|
    format.html # new.html.erb
    format.json { render json: @event }
  end
end

update: The create action is plain vanilla scaffolding code...

def create                                                                                                                                                 
  @event = Event.new(params[:event])

  respond_to do |format|
    if @event.save
      format.html { redirect_to @event, notice: 'Event was successfully created.' }
      format.json { render json: @event, status: :created, location: @event }
    else
      format.html { render action: "new" }
      format.json { render json: @event.errors, status: :unprocessable_entity }
    end
  end
end

If I just insert a title to the Upload form all things running well. But if I select a file as well I run in this error on saving.

NoMethodError: undefined method `name' for nil:NilClass: INSERT INTO "uploads" ("created_at", "filename", "path", "title", "updated_at", "uploadable_id", "uploadable_type") VALUES (?, ?, ?, ?, ?, ?, ?)

The parameters looking fine for me ...

{"utf8"=>"✓",
 "authenticity_token"=>"ppPQnkqXPSbNzRU4KGW11EpzktONZC2DS+hkRQAOnlM=",
 "event"=>{"title"=>"Erstes",
 "uploads_attributes"=>{"0"=>{"title"=>"foo",
 "filename"=>#<ActionDispatch::Http::UploadedFile:0x00000003a2d548 @original_filename="Hazard_E.svg",
 @content_type="image/svg+xml",
 @headers="Content-Disposition: form-data; name=\"event[uploads_attributes][0][filename]\"; filename=\"Hazard_E.svg\"\r\nContent-Type: image/svg+xml\r\n",
 @tempfile=#<File:/tmp/RackMultipart20120721-25352-1ioiss9>>}}},
 "commit"=>"Create Event"}

This is a Rails 3.2.6 app. I've create a new one with the same error as in my development project.

zzeroo
  • 5,466
  • 4
  • 33
  • 49
  • Could you place here `create` action? – melekes Jul 21 '12 at 10:08
  • Question updated, create action is shown at the controller part of her. – zzeroo Jul 21 '12 at 10:16
  • Just a while shot in the dark: What if you changed it to `
    <%= builder.file_field :uploadable %>
    ` This might be a similar issue to http://stackoverflow.com/questions/7055074/adding-multipart-true-throws-undefined-method-name-error
    – Benjamin Tan Wei Hao Jul 21 '12 at 17:06
  • This throws "Can't mass-assign protected attributes: uploadable" even with ```attr_accessible :uploadable``` in my events model... – zzeroo Jul 22 '12 at 14:57

1 Answers1

1

i'm dealing w/ a similar issue, i think you may need to replace the file object with the name of the file in your params hash before you save. params['event']['filename'] is an ActionDispatch::Http::UploadFile object, you probably want that value to be a string..

tttthet
  • 136
  • 1
  • 3
  • Yeah I think so, too. But the question is how? – zzeroo Aug 01 '12 at 23:02
  • I've solved it. Thanx ttthet ;) For my example in the events controller at the create and update action I've added this line: ```@event.process``` In the events model then is the processing action for ftp upload in my app. The jumping point there is to replace the ```event.filename``` with ```event.filename.original_filename``` – zzeroo Aug 03 '12 at 16:21