Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Testing fixtures error NoMethodError: undefined method `type' for nil:NilClass

I have a problem running tests that use fixtures with associations between models.

Here's the error I get, as soon as I run rake test:

ERROR["test_truth", SevenPortfolioTest, 0.005154775]
 test_truth#SevenPortfolioTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_destroy_item_video", SevenPortfolio::ItemVideosControllerTest, 0.008887804]
 test_should_destroy_item_video#SevenPortfolio::ItemVideosControllerTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_index", SevenPortfolio::ItemVideosControllerTest, 0.011364416]
 test_should_get_index#SevenPortfolio::ItemVideosControllerTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_create_item_video", SevenPortfolio::ItemVideosControllerTest, 0.014584266]
 test_should_create_item_video#SevenPortfolio::ItemVideosControllerTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_new", SevenPortfolio::ItemVideosControllerTest, 0.017282812]
 test_should_get_new#SevenPortfolio::ItemVideosControllerTest (0.02s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_update_item_video", SevenPortfolio::ItemVideosControllerTest, 0.019729858]
 test_should_update_item_video#SevenPortfolio::ItemVideosControllerTest (0.02s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_edit", SevenPortfolio::ItemVideosControllerTest, 0.022365633]
 test_should_get_edit#SevenPortfolio::ItemVideosControllerTest (0.02s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_destroy_item", SevenPortfolio::ItemsControllerTest, 0.025860205]
 test_should_destroy_item#SevenPortfolio::ItemsControllerTest (0.03s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_edit", SevenPortfolio::ItemsControllerTest, 0.030867796]
 test_should_get_edit#SevenPortfolio::ItemsControllerTest (0.03s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_show_item", SevenPortfolio::ItemsControllerTest, 0.036687105]
 test_should_show_item#SevenPortfolio::ItemsControllerTest (0.04s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_update_item", SevenPortfolio::ItemsControllerTest, 0.040130774]
 test_should_update_item#SevenPortfolio::ItemsControllerTest (0.04s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_create_item_with_video", SevenPortfolio::ItemsControllerTest, 0.042776553]
 test_should_create_item_with_video#SevenPortfolio::ItemsControllerTest (0.04s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_index", SevenPortfolio::ItemsControllerTest, 0.045301694]
 test_should_get_index#SevenPortfolio::ItemsControllerTest (0.05s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_new", SevenPortfolio::ItemsControllerTest, 0.048094189]
 test_should_get_new#SevenPortfolio::ItemsControllerTest (0.05s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_create_item_with_gallery", SevenPortfolio::ItemsControllerTest, 0.051019403]
 test_should_create_item_with_gallery#SevenPortfolio::ItemsControllerTest (0.05s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass

I'm testing a rails engine. Here's my fixtures:

# test/fixtures/seven_portfolio/items.yml
item_one:
  description: item one description
  finished_at: <%= 7.days.ago %>
  is_featured: true
  item_type: 0

item_two:
  description: item two description
  finished_at: <%= 6.days.ago %>
  is_featured: false
  item_type: 1


# test/fixtures/seven_gallery/galleries.yml
gallery_one:
  title: seven_gallery_gallery_one_title
  item: item_one

# test/fixtures/seven_gallery/photos.yml
photo_one:
  caption: photo_one_caption
  gallery: gallery_one

# test/fixtures/seven_portfolio/item_videos.yml
one:
  item: item_one

When, for example, I remove item: item_one and similar associations lines. The test works well.

-- EDIT

Here's the backtrace

Command failed with status (1): [ruby -I"lib:lib:test"  "/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/**/*_test.rb" ]

/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/testtask.rb:108:in `block (3 levels) in define'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils.rb:57:in `call'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils.rb:57:in `sh'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils_ext.rb:37:in `sh'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils.rb:96:in `ruby'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils_ext.rb:37:in `ruby'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/testtask.rb:104:in `block (2 levels) in define'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils_ext.rb:58:in `verbose'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/testtask.rb:100:in `block in define'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:240:in `call'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:235:in `each'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:235:in `execute'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:165:in `invoke'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:150:in `invoke_task'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:106:in `block (2 levels) in top_level'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:106:in `each'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:106:in `block in top_level'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:115:in `run_with_threads'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:100:in `top_level'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:78:in `block in run'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:75:in `run'
/home/rafael/.rbenv/versions/2.2.0/bin/rake:33:in `<main>'

EDIT

Here's Item class:

module SevenPortfolio
  class Item < ActiveRecord::Base
    has_one :item_video, class_name:'SevenPortfolio::ItemVideo', foreign_key: "seven_portfolio_item_id"
    has_one :item_gallery, class_name: 'SevenGallery::Gallery', foreign_key: "seven_portfolio_item_id"
    accepts_nested_attributes_for :item_video, :item_gallery

    before_save :process_type

    def process_type
      self.build_item_video if self.item_type == 0
      self.build_item_gallery if self.item_type == 1
    end

    def type_content
      self.item_gallery if self.item_type == 0
      self.item_video if self.item_type == 1
    end
  end
end

And Gallery class:

class SevenGallery::Gallery < ActiveRecord::Base
  include SevenGallery::Concerns::Gallery
  belongs_to :item, :class_name => 'SevenPortfolio::Item'
end

EDIT Here's the schema.rb file:

ActiveRecord::Schema.define(version: 20150414145951) do

  create_table "seven_gallery_galleries", force: :cascade do |t|
    t.string   "title",                   limit: 255
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.integer  "seven_portfolio_item_id", limit: 4
  end

  add_index "seven_gallery_galleries", ["seven_portfolio_item_id"], name: "index_seven_gallery_galleries_on_seven_portfolio_item_id", using: :btree

  create_table "seven_gallery_photos", force: :cascade do |t|
    t.string   "caption",                  limit: 255
    t.string   "image",                    limit: 255
    t.integer  "seven_gallery_gallery_id", limit: 4
    t.datetime "created_at",                                             null: false
    t.datetime "updated_at",                                             null: false
    t.boolean  "is_new",                   limit: 1,     default: true
    t.boolean  "is_featured",              limit: 1,     default: false
    t.text     "description",              limit: 65535
    t.string   "alt",                      limit: 255
    t.integer  "position",                 limit: 4,     default: 0
  end

  add_index "seven_gallery_photos", ["seven_gallery_gallery_id"], name: "index_seven_gallery_photos_on_seven_gallery_gallery_id", using: :btree

  create_table "seven_portfolio_item_videos", force: :cascade do |t|
    t.string   "url",                     limit: 255
    t.text     "description",             limit: 65535
    t.string   "title",                   limit: 255
    t.integer  "seven_portfolio_item_id", limit: 4
    t.datetime "created_at",                            null: false
    t.datetime "updated_at",                            null: false
  end

  add_index "seven_portfolio_item_videos", ["seven_portfolio_item_id"], name: "index_seven_portfolio_item_videos_on_seven_portfolio_item_id", using: :btree

  create_table "seven_portfolio_items", force: :cascade do |t|
    t.datetime "created_at",                                null: false
    t.datetime "updated_at",                                null: false
    t.text     "description", limit: 65535
    t.date     "finished_at"
    t.boolean  "is_featured", limit: 1,     default: false
    t.integer  "item_type",   limit: 4,     default: 0
  end

  add_foreign_key "seven_gallery_galleries", "seven_portfolio_items", on_delete: :cascade
  add_foreign_key "seven_gallery_photos", "seven_gallery_galleries", on_delete: :cascade
  add_foreign_key "seven_portfolio_item_videos", "seven_portfolio_items", on_delete: :cascade
end
like image 544
Rafael Adel Avatar asked Apr 16 '15 09:04

Rafael Adel


People also ask

What is an error NoMethodError undefined method for nil NILClass?

Explained. This is a common Ruby error which indicates that the method or attribute for an object you are trying to call on an object has not been defined. For example, the String class in Ruby has the method size (which is synonymous with length , so I can write...

What does undefined method for nil NILClass mean?

The Undefined method for nil:NILClass occurs when you attempt to use a formula on a blank datapill. This indicates that the datapill was not provided any value at runtime.

What is an undefined method in Ruby?

The undefined method is also called the NoMethodError exception, and it's the most common error within projects, according to The 2022 Airbrake Error Data Report. It occurs when a receiver (an object) receives a method that does not exist.

What is no method error in Ruby?

NoMethodError is raised when a method is called on a receiver which doesn't have it defined and also fails to respond with method_missing : "creature".rawr.


2 Answers

I've hit the same errors after migrating and rolling back a few times in my dev environment. It's something to do with the "_type" column.

The only thing that fixed it for me was a drop/create of the test database:

bundle exec rake db:reset RAILS_ENV=test

Be confident your schema.rb is in good shape before doing this.

like image 136
Lucas Nelson Avatar answered Sep 18 '22 09:09

Lucas Nelson


This error happen when in you model you create a relationship that doesnt have a field in the db. Example:

class Contact < ActiveRecord::Base
 belongs_to account
end

But in your table contacts:

create_table "contacts", force: :cascade do |t|
    t.string   "fname"
    t.string   "lname"
    t.string   "title"
    t.string   "description"
    t.datetime "created_at",                 null: false
    t.datetime "updated_at",                 null: false
    t.boolean  "primary"
    t.integer  "contactable_id"
    t.integer  "contactable_type"
  end

See there's no account_id field.

In my case I forgot to update the model's belongs_to to be polymorphic:

class Contact < ActiveRecord::Base
  belongs_to :contactable, polymorphic: true
end

class Account < ActiveRecord::Base
  has_many :contacts, as: :contactable
end
like image 35
juliangonzalez Avatar answered Sep 20 '22 09:09

juliangonzalez