Got a NoMethodError: undefined method `id' for nil:NilClass
Got a NoMethodError: undefined method `id' for nil:NilClass
总结:我是 Rails 上 Ruby 的新手。正在使用 rspec 为编辑功能做 TDD 的 class 分配。我遇到了这个错误:
Failure/Error:访问“/categories/#{category.id}/edit”NoMethodError:nil:NilClass
的未定义方法“id”
我所做的是在 CategoriesController 中定义编辑和更新方法,但错误仍然存在。
请参考以下代码。感谢您的指导。
edit_category_spec.rb:
RSpec.describe 'EditCategories', type: :system do
before do
driven_by(:rack_test)
end
it 'creates category, saves and shows newly created category' do
# visit root route
visit '/'
#click create category link
click_link 'Create Category'
#visit categories/new page
visit '/categories/new'
#fill in form with required info
fill_in 'Name', with: 'This is a category'
#click submit button
click_button 'Create Category'
#expect page to have the content submitted
expect(page).to have_content('This is a category')
end
it 'edits category, saves and shows edited category' do
category = Category.order("id").last
visit "/categories/#{category.id}/edit"
fill_in 'Name', with: 'This is a category edited'
click_button 'Create Category'
expect(page).to have_content('This is a category edited')
end
end ```
categories_controller.rb
```class CategoriesController < ApplicationController
def index
end
def show
@category = Category.find(params[:id])
end
def new
@category = Category.new
end
def create
@category = Category.new(category_params)
if @category.save
redirect_to @category
else
render :new
end
end
def edit
@category = Category.find(params[:id])
end
def update
@category = Category.find(params[:id])
if @category.save
redirect_to @category
else
render :edit
end
end
private
def category_params
params.require(:category).permit(:name)
end
end
Rails 测试是完全独立的(理论上)并且不会在测试之间维护数据。因此,如果您在一个测试中创建了一个类别,然后尝试在另一个测试中访问它(就像您在这里所做的那样),它将无法工作。它以这种方式工作,因此您不会遇到级联故障,但可以离散地测试事物。 Rails 提供了多种方法来创建您随后要测试的数据。 Fixtures 是最简单的,但是你也可以使用像 FactoryGirl 这样的 gem。
解决您的问题的最简单方法是将这两种测试方法(it 'creates category, saves and shows newly created category'
和 it 'edits category, saves and shows edited category'
)合并为一个方法,该方法首先创建然后编辑类别记录。
更好的做法是将它们分开(因为您的测试套件很快就会变得庞大而复杂,您需要将它们分开),并在测试前使用固定装置设置您的记录。
最后,当您编写测试时,不要忘记编写捕获失败的测试 - 例如,如果提供的数据无效,您的代码应该拒绝创建或编辑记录。
总结:我是 Rails 上 Ruby 的新手。正在使用 rspec 为编辑功能做 TDD 的 class 分配。我遇到了这个错误:
Failure/Error:访问“/categories/#{category.id}/edit”NoMethodError:nil:NilClass
的未定义方法“id”我所做的是在 CategoriesController 中定义编辑和更新方法,但错误仍然存在。
请参考以下代码。感谢您的指导。
edit_category_spec.rb:
RSpec.describe 'EditCategories', type: :system do
before do
driven_by(:rack_test)
end
it 'creates category, saves and shows newly created category' do
# visit root route
visit '/'
#click create category link
click_link 'Create Category'
#visit categories/new page
visit '/categories/new'
#fill in form with required info
fill_in 'Name', with: 'This is a category'
#click submit button
click_button 'Create Category'
#expect page to have the content submitted
expect(page).to have_content('This is a category')
end
it 'edits category, saves and shows edited category' do
category = Category.order("id").last
visit "/categories/#{category.id}/edit"
fill_in 'Name', with: 'This is a category edited'
click_button 'Create Category'
expect(page).to have_content('This is a category edited')
end
end ```
categories_controller.rb
```class CategoriesController < ApplicationController
def index
end
def show
@category = Category.find(params[:id])
end
def new
@category = Category.new
end
def create
@category = Category.new(category_params)
if @category.save
redirect_to @category
else
render :new
end
end
def edit
@category = Category.find(params[:id])
end
def update
@category = Category.find(params[:id])
if @category.save
redirect_to @category
else
render :edit
end
end
private
def category_params
params.require(:category).permit(:name)
end
end
Rails 测试是完全独立的(理论上)并且不会在测试之间维护数据。因此,如果您在一个测试中创建了一个类别,然后尝试在另一个测试中访问它(就像您在这里所做的那样),它将无法工作。它以这种方式工作,因此您不会遇到级联故障,但可以离散地测试事物。 Rails 提供了多种方法来创建您随后要测试的数据。 Fixtures 是最简单的,但是你也可以使用像 FactoryGirl 这样的 gem。
解决您的问题的最简单方法是将这两种测试方法(it 'creates category, saves and shows newly created category'
和 it 'edits category, saves and shows edited category'
)合并为一个方法,该方法首先创建然后编辑类别记录。
更好的做法是将它们分开(因为您的测试套件很快就会变得庞大而复杂,您需要将它们分开),并在测试前使用固定装置设置您的记录。
最后,当您编写测试时,不要忘记编写捕获失败的测试 - 例如,如果提供的数据无效,您的代码应该拒绝创建或编辑记录。