Search code examples
ruby-on-railsruby-on-rails-3.2factory-botrspec-rails

Undefined method `to_i' for <Array:0x########> whilst testing using factories


I have this problem using FactoryGirl.

Each time I run the test, it comes up with the error: Undefined method `to_i' for Array

I cannot see where it is trying to convert to an integer. My best guess is it is trying to save the client record as a number, instead of just saving the ID of the record. I have tried searching for documentation to see if I have set up my factories incorrectly.

I have run rake db:test:prepare in the hope it was that.

Are you able to see what is going wrong?

spec/factories.rb

FactoryGirl.define do

  factory :client do
    name     "Example"
    email    "[email protected]"
  end

  factory :book do
    title    "Book Title"
    client_id  {[FactoryGirl.create(:client)]}
  end

end

spec/views/books/index.html.erb_spec.rb

require 'spec_helper'

describe "books/index" do
  before do
    FactoryGirl.create(:book)
  end

  it "renders a list of books" do
    render
    # Run the generator again with the --webrat flag if you want to use webrat matchers
    assert_select "tr>td", :text => "Title".to_s, :count => 2
    assert_select "tr>td", :text => 1.to_s, :count => 2
  end
end

Test output

  1) books/index renders a list of books
     Failure/Error: FactoryGirl.create(:book)
     NoMethodError:
       undefined method `to_i' for #<Array:0x########>
     # ./spec/views/books/index.html.erb_spec.rb:5:in `(root)'

Solution

  • You made a mistake at defining factories.

    Do not call FactoryGirl.create... inside a definition.

    Assume book has many clients(that's weird though), you can just mention book inside client. Like this

    FactoryGirl.define do
    
      factory :client do
        name     "Example"
        email    "[email protected]"
        book # Revised here. book refers to the symbol :book
      end
    
      factory :book do
        title    "Book Title"
      end
    
    end
    

    That's all. You test should be able to past.

    P.S Side note about model association:

    In your setting, one client could only have one book! The business owner can't get rich soon by selling like that. A proper logic should be:

    A client can have many orders

    An order can have many items

    An item has only one book(id), but may have many pieces.

    But that's another story though.