我正在使用acts_as_audited。在destroy操作的控制器中,我传递了审计注释值。所有这一切都运作良好,但当我尝试测试我得到的销毁动作时:
PurchasesController DELETE /destroy deletes the correct Purchase
Failure/Error: delete :destroy, id: i
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]
# ./app/controllers/purchases_controller.rb:79:in `destroy'
# ./spec/controllers/purchases_controller_spec.rb:156:in `block (3 levels) in <top (required)>'
第79行读取:@purchase.audit_comment = params[:purchase][:audit_comment]
继承我的代码:
PurchasesController
def destroy
@purchase = Purchase.find(params[:id])
@purchase.audit_comment = params[:purchase][:audit_comment]
respond_to do |format|
if @purchase.destroy
format.html { redirect_to(purchases_url, notice: "Successfully destroyed purchase.") }
format.xml { render :xml => @purchase, :status => :deleted, :location => @purchase }
else
flash[:alert] = "#{@purchase.po_number} could not be destroyed"
render 'show'
end
end
end
购买show.html.erb 已编辑
<%= form_for @purchase, method: :delete do |builder| %>
<% if @purchase.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@purchase.errors.count, "error") %> prohibited this purchase from being saved:</h2>
<ul>
<% @purchase.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% title "Purchase" %>
<div id="delete_button">
<span><strong>PO Number: <%= @purchase.po_number %></strong></span>
<%= render "audit_comment", f: builder %>
<%= builder.submit "Destroy Purchase"%>
</div>
<% end %>
<p>
<%= link_to "Edit", edit_purchase_path(@purchase) %> |
<%= link_to "View All", purchases_path %>
</p>
_audit_comment.html.erb - 购买
<div id = "audit">
<%= f.label :audit_comment %>:<br />
<%= f.text_area :audit_comment, :size => "60x5" %>
</div>
purchase_controller_spec.rb
require 'spec_helper'
require 'ruby-debug'
describe PurchasesController do
login_user
render_views
before(:each) do
@purchase = Factory(:purchase)
end
describe "DELETE /destroy" do
before(:each) do
@ability.can :destroy, Purchase
end
it "deletes the correct Purchase" do
i = @purchase.id
c = Purchase.count
pl = Purchase.find(i).purchase_line_items
cpl = pl.count
delete :destroy, id: i
Purchase.count.should == c-1
pl.count.should == cpl-1
response.should redirect_to(purchases_path)
flash[:notice].should == "Successfully destroyed purchase."
end
it "redirects to the index page with an alert when a delete fails" do
i = @purchase.id
c = Purchase.count
pl = Purchase.find(i).purchase_line_items
cpl = pl.count
Purchase.any_instance.stubs(:valid?).returns(:false)
delete :destroy, id: i
Purchase.count.should_not == c-1
pl.count.should_not == cpl-1
response.should render_template('show')
flash[:alert].should == "#{@purchase.po_number} could not be destroyed"
end
end
end
感谢任何帮助。谢谢!
答案 0 :(得分:2)
它告诉你,在第79行,params[:purchase]
是零。
它的原因是button_to
生成自己的表单标记。因此,您现在<form>
内有<form>
,并且您的审核评论字段未提交。您应该使用button_to
而不是builder.submit
。您还需要在致电:method
时设置form_for
选项,以使其成为DELETE
请求。
修改后更新
HTML现在看起来不错,但我发现规范存在问题。我想您忘记将审核评论传递给您的HTTP参数。它存在于HTML中,但是您的规范会绕过表单,因为它会单独测试控制器。 (集成测试将使用实际形式。控制器测试不会。)因此,您必须手动将任何形式的控制器期望的参数添加到请求中。例如:
delete :destroy, :id => 1, :purchase => {:audit_comment => 'Test comment'}