Rails + CarrierWave: NoMethodError: undefined method `name' for nil:NilClass
Asked Answered
G

6

7

I am using CarrierWave with Rails 3.1. I am getting the following error message when I submit the form (trying to upload an image):

Error Message:

ActiveRecord::StatementInvalid in Admin::PostsController#create

NoMethodError: undefined method `name' for nil:NilClass: INSERT INTO "posts" ("body", "created_at", "draft", "image", "post_type", "title", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?)
Rails.root: /Users/aziz/Sandbox/ruby/rails/Tumblelog

Application Trace | Framework Trace | Full Trace
app/controllers/admin/posts_controller.rb:18:in `create'
Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"za+zNRDGNCcujnCmO726cWCo2ze1rgaXv5bL17JGaek=",
 "post"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x000001014aeff0 @original_filename="AzizLight.jpeg",
 @content_type="image/jpeg",
 @headers="Content-Disposition: form-data; name=\"post[image]\"; filename=\"AzizLight.jpeg\"\r\nContent-Type: image/jpeg\r\n",
 @tempfile=#<File:/var/folders/ky/2ddtbt0d7k1g__2ctr8njcfc0000gn/T/RackMultipart20110918-21704-hp2ajt>>,
 "draft"=>"0",
 "user_id"=>"2",
 "post_type"=>"image"},
 "commit"=>"Post"}

The problem is that I don't know where this name comes from and I don't know what variable is being nil, so I can't debug properly (I tried to debug a log before asking here). Line 18 corresponds to the @post.save line in the following controller:

PostsController:

# ...

def new
  @post = Post.new
  @form_html_options = (params[:post_type] == "image") ? { :multipart => true } : {}
  @form_partial = get_form_partial(params[:post_type])
  redirect_to admin_posts_path, :alert => "You tried to create an unknown type of post..." if @form_partial.nil?
  @title = "Creating a new post..."
end

def create
  @post = Post.new(params[:post])
  if @post.save
    flash[:success] = "Post created successfully!"
    redirect_to admin_post_path(@post)
  else
    @title = "Creating a new post..."
    @form_partial = get_form_partial(params[:post][:post_type])
    render 'new'
  end
end

# ...

Here other files that might be needed to spot the problem:

Post (model):

attr_accessible :title, :body, :user_id, :draft, :post_type, :image

belongs_to :user

mount_uploader :image_url, ImageUploader

ImageUploader:

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  storage :fog

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

new.html.erb:

<h1><%= @title %></h1>

<%= form_for @post, :url => admin_posts_path, :html => @form_html_options do |f| %>
  <%= render 'form', :f => f %>
<% end %>

_form.html.erb:

<%= render 'error_messages' %>

<%= render @form_partial, :f => f %>

<p class="drop-down">
  <%= f.label :draft, 'Status' %>
  <%= f.select(:draft, options_for_select([["Published", 0], ["Draft", 1]], (@post.new_record? ? 0: @post.draft))) %>
</p>

<%= f.hidden_field :user_id, :value => @post.user_id || current_user.id %>
<%= f.hidden_field :post_type, :value => @post.post_type || params[:post_type] %>

<p class="button"><%= f.submit "Post", :disable_with => 'Posting...' %></p>

_image_form.html.erb (@form_partial):

<p><%= f.file_field :image %></p>

So what it really going on please?

Giacinta answered 18/9, 2011 at 21:16 Comment(1)
The mount_uploader should be only image, right? Not image_url?Archfiend
M
4

Your image uploader class was not loaded into your current rails server thread. Reload rails server and it should work fine =).

Microdont answered 14/11, 2011 at 7:59 Comment(1)
Thanks, I had the same symptom and my uploader class had errors in it that prevented it from loading properly. Too bad the error message is not better.Fortuity
W
2

Make sure you use - mount_uploader :image, ImageUploader in your model like here -

class CarImage < ActiveRecord::Base 
  belongs_to :car
  mount_uploader :image, ImageUploader
end

Regards

Robbie

Waylen answered 10/10, 2011 at 13:25 Comment(0)
K
2

I experienced the some problem and the cause is (probably always) that the UploadedFile object has been sent to the attribute carrierwave was mounted on. The db adapter cannot serialize this object and will therefore throw this error.

Make sure that:

  • the uploader has been properly mounted
  • you don't use write_attribute to write the uploaded file (which was the cause of my problem). Use the accessor instead: model.send('image=', params[:model][:image]). Uglier, but better.
Kimura answered 29/11, 2011 at 12:34 Comment(1)
I used my own utility method to assign the attribute, which used user['profile_photo'] syntax and this generated the same exception. Using #send worked fine. I wonder when would I have found the problem without you mentioning this. Thanks!Giliana
S
2

Make sure in your model:

mount_uploader :image, ImageLoader

Remember that :image must be the string/text type.

Syphilology answered 26/12, 2013 at 22:33 Comment(0)
G
1

I came across this post because I had the same error you described, but restarting the server didn't resolve it (as suggested by other answers). In my case, the problem was caused because I used mount_uploader before attr_accessible. By switching them I solved the problem.

Gerfalcon answered 26/1, 2013 at 22:1 Comment(0)
D
0

I had a similar problem. Solution was changing:

attr_accessible :title, :body, :user_id, :draft, :post_type, :image
belongs_to :user
mount_uploader :image_url, ImageUploader

to:

attr_accessible :title, :body, :user_id, :draft, :post_type, :image_url
belongs_to :user
mount_uploader :image_url, ImageUploader
Daune answered 29/8, 2013 at 19:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.