我正在学习轨道,而且我不确定为什么我会遇到此测试失败/错误。任何解释都会很棒!我想要一个解决方案,但我真正需要的是理解为什么我首先会遇到这种失败,所以我知道将来如何处理这个问题。
Rails版本是4.1.1, Ruby版本2.0.0p353, Rspec版本3.0.1, Capybara 2.3.0
这是错误
Failure/Error: click_link "New Todo Item"
NoMethodError:
undefined method `todo_item' for nil:NilClass
# ./app/controllers/todo_items_controller.rb:8:in `new'
# ./spec/features/todo_items/create_spec.rb:16:in `block (2 levels) in <top (required)>'
这是它所指的控制器 应用程序/控制器/ todo_items_controller.rb
class TodoItemsController < ApplicationController
def index
@todo_list = TodoList.find(params[:todo_list_id])
end
def new
@todo_item = TodoList.find(params[:todo_list_id])
@todo_item = @todo_list.todo_items.new
end
end
这是测试 规格/特征/ todo_items / create_spec.rb
require 'rails_helper'
describe "Viewing todo items" do
let!(:todo_list) { TodoList.create(title: "Grocery List", description: "Groceries")}
def visit_todo_list(list)
visit "/todo_lists"
within "#todo_list_#{list.id}" do
click_link "List Items"
end
end
it "is successful with valid content" do
visit_todo_list(todo_list)
click_link "New Todo Item"
fill_in "Content", with: "Milk"
click_button "Save"
expect(page).to have_content("Added Todo List Item.")
within("ul.todo_items") do
expect(page).to have_content("Milk")
end
end
end
这是与之相关的观点。 应用程序/视图/ todo_items / index.html.erb
<h1><%= @todo_list.title %></h1>
<p>testing 123</p>
<ul class="todo_items">
<% @todo_list.todo_items.each do |todo_item| %>
<li><%= todo_item.content %></li>
<% end %>
</ul>
<p>
<%= link_to "New Todo Item", new_todo_list_todo_item_path %>
</p>
如果您还有其他需要,请告诉我,并提前感谢您!
最佳,
杰克逊
答案 0 :(得分:3)
@todo_item为零,因为您没有在新方法中定义@todo_list。您希望新方法看起来像这样:
def new
@todo_list = TodoList.find(params[:todo_list_id])
@todo_item = @todo_list.todo_items.new
end
但是,这不是很干,因为您已经在索引方法中定义了@todo_list。你应该创建一个名为set_list的新方法,然后使用before_action在相关方法之前调用它。
before action :set_list
def new
@todo_item = @todo_list.todo_items.new
end
private
def set_list
@todo_list = TodoList.find(params[:todo_list_id])
end