[英]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
: 一旦我运行
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. 我正在测试一个rails引擎。 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. 例如,当我删除
item: item_one
和类似的关联item: item_one
。 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: 这是
Item
类:
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: 和
Gallery
类:
class SevenGallery::Gallery < ActiveRecord::Base
include SevenGallery::Concerns::Gallery
belongs_to :item, :class_name => 'SevenPortfolio::Item'
end
EDIT Here's the schema.rb
file: 编辑这是
schema.rb
文件:
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
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.
这与“_type”列有关。
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. 在执行此操作之前,请确保您的
schema.rb
处于良好状态。
This error happen when in you model you create a relationship that doesnt have a field in the db. 在模型中创建一个在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. 看到没有account_id字段。
In my case I forgot to update the model's belongs_to
to be polymorphic: 在我的情况下,我忘了更新模型的
belongs_to
是多态的:
class Contact < ActiveRecord::Base
belongs_to :contactable, polymorphic: true
end
class Account < ActiveRecord::Base
has_many :contacts, as: :contactable
end
Is this not a duplicate/similar problem to this issue? 这不是这个问题的重复/类似问题吗?
Loading Rails Fixtures in a Specific Order when Testing 测试时按特定顺序装载导轨夹具
What could be happening is your fixtures are not being loaded in the correct order so when item is referenced it comes up as nil. 可能发生的事情是你的灯具没有以正确的顺序加载,因此当引用项目时它会出现为零。
From the response of the other answer you can try 从其他答案的回答你可以尝试
Here's how you fix your issue: 以下是解决问题的方法:
Log into Postgresql with your default superuser (mine is "postgres") Perform the following command: 使用默认超级用户登录Postgresql(我的是“postgres”)执行以下命令:
ALTER ROLE yourtestdbuser WITH SUPERUSER; ALTER ROLE yourtestdbuser with SUPERUSER;
Enjoy your properly working fixtures. 享受你正常工作的灯具。
If you are using mysql it is probably similar issue. 如果您使用的是mysql,那可能是类似的问题。
TL;DR: People are landing on this question for different reasons. TL; DR:人们出于不同的原因登陆这个问题。 My problem/solution is described in 'Fixing the error'.
我的问题/解决方案在“修复错误”中描述。 I hope this extended explanation will help you learn why you're experiencing this cryptic error, and save you some time debugging it.
我希望这个扩展的解释将帮助您了解为什么您遇到这个神秘的错误,并节省您一些时间调试它。
I had almost the same error when running my tests: NoMethodError: undefined method 'id' for nil:NilClass
, or NoMethodError: undefined method 'each' for nil:NilClass
. 我在运行测试时遇到了几乎相同的错误:
NoMethodError: undefined method 'id' for nil:NilClass
,或NoMethodError: undefined method 'each' for nil:NilClass
。 There were no line numbers to reference, and Lucas' answer of rebuilding would sometimes work and then would stop working; 没有行号可供参考, 卢卡斯的重建答案 有时会起作用,然后就会停止工作; I'd later learn this is because of caching and loading order of fixture files.
我后来才知道这是因为夹具文件的缓存和加载顺序。
My error was with how my fixtures were setup. 我的错误在于如何设置我的灯具。 I found this by running my tests with a full backtrace described in this StackOverflow answer :
我通过在StackOverflow回答中描述的完整回溯运行我的测试找到了这个:
BACKTRACE=YES rake test test/controllers/document_submissions_controller_test.rb
This pointed to the gem files in ActiveSupport that were throwing the error. 这指向ActiveSupport中抛出错误的gem文件。 Here's my full log for a single test:
这是我单个测试的完整日志:
So it seems the error is in loading my fixtures, since the error is originating in active_record/fixtures.rb:758
(see highlighted line above). 所以似乎错误在于加载我的灯具,因为错误源自
active_record/fixtures.rb:758
(见上面突出显示的行)。 However, I have a large amount of fixtures in my app, I needed to narrow down which in particular was causing the problem. 但是,我的应用程序中有大量的灯具,我需要缩小范围,特别是导致问题。
I opened the active_record/fixtures.rb:758
file in my code editor using the command below: 我使用以下命令在代码编辑器中打开了
active_record/fixtures.rb:758
文件:
code /Users/mattmcinnis/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.0/lib/active_record/fixtures.rb
Note: I'm using VSCode with the code
command, but any code editor will do. 注意:我正在使用VSCode和
code
命令,但任何代码编辑器都可以。
On line 758 where the error occurs, I saw this code: 在发生错误的第758行,我看到了这段代码:
FixtureSet::File.open(file) do |fh|
fh.each do |fixture_name, row| # line 758
fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
end
end
..which I wrapped in a rescue block, and modified to: ..我在救援区包裹,并修改为:
FixtureSet::File.open(file) do |fh|
begin
fh.each do |fixture_name, row|
fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
end
rescue
debugger
end
end
NOTE: Be sure to revert any changes to this file when you're done! 注意:完成后,请务必还原对此文件的任何更改!
I'm interested in which file, captured in the loop above in the variable fh
, was causing the error. 我感兴趣的是在变量
fh
上面循环中捕获的文件导致了错误。 Running my test suite again I hit my breakpoint and found the filename that was causing the problem: 再次运行我的测试套件我点击我的断点并找到导致问题的文件名:
> (byebug) fh
=> ... @file="permissions.yml"
In my permissions.yml
file, my fixture is referring to a related model by hard coding the 'id' in, instead of referring by name: 在我的
permissions.yml
文件中,我的fixture通过硬编码'id'来引用相关模型,而不是通过名称引用:
Ex. 防爆。
permissions.yml
permission1:
...
user_id: <%= User.first.id %> # Bad!
Fixing the last line to something like, user: user1
to refer to the user1
fixture in users.yml
solved the issue. 修复最后一行,例如
user: user1
引用users.yml
的user1
fixture解决了这个问题。
Hope this helps someone. 希望这有助于某人。 I lost half a day on this one, and found it super hard to diagnose.
我在这一天失去了半天,发现诊断起来非常困难。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.