1

我刚刚将我的应用程序从 Rails 3.2 升级到 Rails 4。

我正在努力完成需要做出的各种改变,但这个让我很难过。

我的销毁操作似乎在应用程序中起作用,但是当我运行我的 rspec 测试时,它们失败了。

这是我的控制器中似乎抛出错误的方法(当我将其注释掉时,测试运行没有问题)。

def undo_link
  view_context.link_to("Undo archive.", revert_version_path(@answer.versions.scoped.last), :method => :post)
end

这条线取自 Ryan Bates 的Undo with PaperTrail Railscast。它生成的链接似乎在应用程序中运行良好。

以下是 rspec 测试:

describe 'DELETE #destroy' do
  it 'deletes the answer from the database' do
    expect{ delete :destroy, :id => @answer1, :question_id => @question1 }.to change(Answer, :count).by(-1)
  end
  it 'redirects to questionss#show' do
    delete :destroy, :id => @answer1, :question_id => @question1
    expect(response).to redirect_to @question1
  end
end

这是抛出的 rspec 错误:

1) AnswersController Admin access DELETE #destroy 从数据库中删除答案

失败/错误:expect{ delete :destroy, :id => @answer1, :question_id => @question1 }.to change(Answer, :count).by(-1)

ActionController::UrlGenerationError:

没有路由匹配 {:id=>nil} 缺少必需的键:[:id]

# ./app/controllers/answers_controller.rb:87:in `undo_link'

# ./app/controllers/answers_controller.rb:69:in `block (2 levels) in destroy'

# ./app/controllers/answers_controller.rb:68:in `destroy'

# ./spec/controllers/answers_controller_spec.rb:179:in `block (5 levels) in '

# ./spec/controllers/answers_controller_spec.rb:179:in `block (4 levels) in '

2) AnswersController 管理员访问 DELETE #destroy 重定向到 questions#show

失败/错误:删除 :destroy, :id => @answer1, :question_id => @question1 ActionController::UrlGenerationError: 没有路由匹配 {:id=>nil} 缺少必需的键:[:id]

# ./app/controllers/answers_controller.rb:87:in `undo_link'

    # ./app/controllers/answers_controller.rb:69:in `block (2 levels) in destroy'

    # ./app/controllers/answers_controller.rb:68:in `destroy'

    # ./spec/controllers/answers_controller_spec.rb:182:in `block (4 levels) in <top (required)>'

谁能解释为什么会发生这种情况以及我能做些什么?

编辑 - 2013 年 12 月 9 日

正如 Mikhail 在评论中建议的那样,我在使用 better_errors gem 的方法中提出了一个错误,以便尝试重现 nil。我从来没有在应用程序本身中得到 nil - 它似乎只出现在 rspec 测试中。这是我得到的结果:

>> @answer.versions.scoped.last
=> #<PaperTrail::Version id: 64, item_type: "Answer", item_id: 8, event: "destroy", whodunnit: "6", object: "---\nid: 8\nbody: <p>Shoreditch enim retro, disrupt s...", created_at: "2013-12-09 16:35:08">
>> revert_version_path(@answer.versions.scoped.last)
=> "/versions/64/revert"
>> view_context.link_to("Undo archive.", revert_version_path(@answer.versions.scoped.last), :method => :post)
=> "<a data-method=\"post\" href=\"/versions/64/revert\" rel=\"nofollow\">Undo archive.</a>"

编辑 - 2013 年 12 月 10 日

这是设置@answer1 的 rspec 代码:

before :each do
  @question1 = create(:question, :id => 99)
  @answer1 = create(:answer, :question_id => 99)
  sign_in_user(:admin)
end

和工厂:

FactoryGirl.define do
  factory :answer do
    body { Faker::Lorem.characters(150) }
    user_id { 1 }
    question_id { 1 }
  end
end
4

0 回答 0