集成测试时 nil:NilClass 的未定义方法“each”
undefined method `each' for nil:NilClass upon integration test
我正在 Rails 上使用 Ruby 开发一个网络应用程序,因为我对它还是很陌生,我忘记了我应该在我的应用程序代码之前编写测试和不想重做所以在我编写测试之前,我已经编写了我的应用程序代码并且它在浏览器上运行良好,但是在我编写集成测试之后,我有一大堆 ActionView::Template::Error: undefined method
each' for nil:NilClass` 错误。
例如,我将复制并粘贴一个错误,我希望这些答案可以推断出我的其他类似错误。
错误:
ERROR["test_unsuccessful_edit", TransactionEditTest, 0.560911]
test_unsuccessful_edit#TransactionEditTest (0.56s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `each' for nil:NilClass
app/views/transactions/index.html.erb:4:in `_app_views_transactions_index_html_erb___2730839601929560472_70220029186400'
app/controllers/transactions_controller.rb:32:in `update'
test/integration/transaction_edit_test.rb:14:in `block in <class:TransactionEditTest>'
app/views/transactions/index.html.erb:4:in `_app_views_transactions_index_html_erb___2730839601929560472_70220029186400'
app/controllers/transactions_controller.rb:32:in `update'
test/integration/transaction_edit_test.rb:14:in `block in <class:TransactionEditTest>'
16/16: [=================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.59370s
对应的集成测试:
require 'test_helper'
class TransactionEditTest < ActionDispatch::IntegrationTest
def setup
@transaction = transactions(:test)
end
test "unsuccessful edit" do
get edit_transaction_path(@transaction)
assert_template 'transactions/edit'
patch transaction_path(@transaction), transaction: { from: "",
to: "",
amount: "foo",
description: "bar" }
assert_template 'transactions/edit'
end
这是我的控制器:
class TransactionsController < ApplicationController
def index
@transactions = Transaction.all
end
def show
@transaction = Transaction.find(params[:id])
end
def new
@transaction = Transaction.new
end
def create
if @transaction.save
@transactions = Transaction.all
render 'index'
else
render 'new'
end
end
def edit
@transaction = Transaction.find(params[:id])
end
def update
@transaction = Transaction.find(params[:id])
if @transaction.update_attributes(transaction_params)
redirect_to(:action => 'index')
else
render('edit')
end
end
def destroy
Transaction.find(params[:id]).destroy
redirect_to transactions_path
end
private
def transaction_params
params.require(:transaction).permit(:from, :to, :amount,
:description)
end
end
和我的index.html.erb
<div class="transaction_list">
<% @transactions.each do |transaction| %>
<li>
<%= transaction.from %>
<%= transaction.to %>
<%= number_with_precision(transaction.amount, :precision => 2) %>
<%= transaction.description %>
<%= link_to "Edit", edit_transaction_path(transaction.id) %> |
<%= link_to "Delete", transaction, method: :delete, data: { confirm: "Are you sure?" } %>
</li>
<% end %>
</div>
我知道很多人已经在Whosebug上问过这个问题,但是我找不到和我有类似情况的人,我希望有人不仅指出我的错误,还给我解释一下概念,非常感谢!!
尝试
def update
@transaction = Transaction.find(params[:id])
@transaction.update_attributes(transaction_params)
redirect_to(:action => 'index')
end
或
def update
@transaction = Transaction.find(params[:id])
if @transaction.update_attributes(transaction_params)
redirect_to(:action => 'index')
else
@transactions = Transaction.all
render('index')
end
end
基本上,你需要在渲染前设置@transactions
变量
我正在 Rails 上使用 Ruby 开发一个网络应用程序,因为我对它还是很陌生,我忘记了我应该在我的应用程序代码之前编写测试和不想重做所以在我编写测试之前,我已经编写了我的应用程序代码并且它在浏览器上运行良好,但是在我编写集成测试之后,我有一大堆 ActionView::Template::Error: undefined method
each' for nil:NilClass` 错误。
例如,我将复制并粘贴一个错误,我希望这些答案可以推断出我的其他类似错误。
错误:
ERROR["test_unsuccessful_edit", TransactionEditTest, 0.560911]
test_unsuccessful_edit#TransactionEditTest (0.56s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `each' for nil:NilClass
app/views/transactions/index.html.erb:4:in `_app_views_transactions_index_html_erb___2730839601929560472_70220029186400'
app/controllers/transactions_controller.rb:32:in `update'
test/integration/transaction_edit_test.rb:14:in `block in <class:TransactionEditTest>'
app/views/transactions/index.html.erb:4:in `_app_views_transactions_index_html_erb___2730839601929560472_70220029186400'
app/controllers/transactions_controller.rb:32:in `update'
test/integration/transaction_edit_test.rb:14:in `block in <class:TransactionEditTest>'
16/16: [=================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.59370s
对应的集成测试:
require 'test_helper'
class TransactionEditTest < ActionDispatch::IntegrationTest
def setup
@transaction = transactions(:test)
end
test "unsuccessful edit" do
get edit_transaction_path(@transaction)
assert_template 'transactions/edit'
patch transaction_path(@transaction), transaction: { from: "",
to: "",
amount: "foo",
description: "bar" }
assert_template 'transactions/edit'
end
这是我的控制器:
class TransactionsController < ApplicationController
def index
@transactions = Transaction.all
end
def show
@transaction = Transaction.find(params[:id])
end
def new
@transaction = Transaction.new
end
def create
if @transaction.save
@transactions = Transaction.all
render 'index'
else
render 'new'
end
end
def edit
@transaction = Transaction.find(params[:id])
end
def update
@transaction = Transaction.find(params[:id])
if @transaction.update_attributes(transaction_params)
redirect_to(:action => 'index')
else
render('edit')
end
end
def destroy
Transaction.find(params[:id]).destroy
redirect_to transactions_path
end
private
def transaction_params
params.require(:transaction).permit(:from, :to, :amount,
:description)
end
end
和我的index.html.erb
<div class="transaction_list">
<% @transactions.each do |transaction| %>
<li>
<%= transaction.from %>
<%= transaction.to %>
<%= number_with_precision(transaction.amount, :precision => 2) %>
<%= transaction.description %>
<%= link_to "Edit", edit_transaction_path(transaction.id) %> |
<%= link_to "Delete", transaction, method: :delete, data: { confirm: "Are you sure?" } %>
</li>
<% end %>
</div>
我知道很多人已经在Whosebug上问过这个问题,但是我找不到和我有类似情况的人,我希望有人不仅指出我的错误,还给我解释一下概念,非常感谢!!
尝试
def update
@transaction = Transaction.find(params[:id])
@transaction.update_attributes(transaction_params)
redirect_to(:action => 'index')
end
或
def update
@transaction = Transaction.find(params[:id])
if @transaction.update_attributes(transaction_params)
redirect_to(:action => 'index')
else
@transactions = Transaction.all
render('index')
end
end
基本上,你需要在渲染前设置@transactions
变量