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')合并为一个方法,该方法首先创建然后编辑类别记录。

更好的做法是将它们分开(因为您的测试套件很快就会变得庞大而复杂,您需要将它们分开),并在测试前使用固定装置设置您的记录。

最后,当您编写测试时,不要忘记编写捕获失败的测试 - 例如,如果提供的数据无效,您的代码应该拒绝创建或编辑记录。