Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What parameters do I need to pass in the controller to a Carrierwave-mounted model?

I have an Artwork model with an image attribute where Carrierwave is mounted. While writing controller specs I realized that the image field stays blank, even when I thought I was passing in a file object.

My debug info tells me that the problem is with the image attribute I have CarrierWave mounted on, and not something else. I don't think I'm passing in the information it needs, but I don't know what to try.

Here's the the controller action, with some debug information to identify the problem:

def create
    @artwork = @imageable.artworks.new(params[:artwork])
    logger.debug "Artwork should be valid: #{@artwork.valid?}"
    logger.debug "Errors: #{@artwork.errors.full_messages}"
    if @artwork.save
        flash[:success] = "Artwork created."
        redirect_to [@imageable, :artworks]
    else
        flash[:error] = "Artwork not created."
        render :new
    end
end

In the test log I see this after running my specs:

Processing by ArtworksController#create as HTML
  Parameters: {"artwork"=>{"image"=>"#<File:0x4515480>", "title"=>"Portrait","year"=>"2012", "surface_type"=>"canvas", "size"=>"10 x 10", "price"=>"100.0", "for_sale"=>false, "prints_available"=>false, "notes"=>"extra notes"}, "file"=>"#<File:0x46c6938>", "originals_gallery_id"=>"1"}
[1m[36mOriginalsGallery Load (0.0ms)[0m  [1mSELECT "originals_galleries".* FROM   "originals_galleries" WHERE "originals_galleries"."id" = ? LIMIT 1[0m  [["id", "1"]]
Artwork should be valid: false
Errors: ["Image can't be blank"]

Any thoughts, please? Is there a controller param I'm forgetting to set?

like image 265
hlh Avatar asked Jan 09 '13 01:01

hlh


1 Answers

My problem was a more general one: during my tests (with Rspec and FactoryGirl) I was passing in the wrong kind of file object to the controller action. This is the kind of object I was defining for my image attribute:

FactoryGirl.define do
  factory :artwork do
    image { File.open(File.join(Rails.root, 'spec', 'support', 'sample.gif')) }
    ...other attributes omitted
  end
end

The above is the setup that Carrierwave docs recommended for FactoryGirl test fixtures. It worked for testing the model and most controller actions, but not for the create action.

My test logs were telling me that my image attribute was blank, despite passing in this File object. After some searching I found out that you could pass in an instance of Rack::Test::UploadedFile (I think that ActionDispatch::Http::UploadedFile is what's submitted through the browser(?)).

So instead of the image attribute being set to File.open(...) in the factory, I set it to Rack::Test::UploadedFile.new(Rails.root.join("spec/support/sample.gif")). My controller specs passed and the file upload was saved to the database.

I think this helps explain why a lot of people witness successful file uploads in the browser, but not in their tests or validations.

This post about testing file attachments in Rails 3 really helped.

like image 157
hlh Avatar answered Sep 21 '22 19:09

hlh