I just upgraded my app from Rails 3.2 to Rails 4.
I'm working through the various changes that need to be made, but this one is stumping me.
My destroy actions seems to be working in the app, but when I run my rspec tests, they are failing.
This is the method in my controller that seems to be throwing the error (when I comment it out, the tests run without issue).
def undo_link
view_context.link_to("Undo archive.", revert_version_path(@answer.versions.scoped.last), :method => :post)
end
The line is taken from Ryan Bates' Undo with PaperTrail Railscast. The link that it generates is seems working perfectly in the app.
Here are the rspec tests:
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
And here is the rspec error that is thrown:
1) AnswersController Admin access DELETE #destroy deletes the answer from the database
Failure/Error: expect{ delete :destroy, :id => @answer1, :question_id => @question1 }.to change(Answer, :count).by(-1)
ActionController::UrlGenerationError:
No route matches {:id=>nil} missing required keys: [: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 Admin access DELETE #destroy redirects to questionss#show
Failure/Error: delete :destroy, :id => @answer1, :question_id => @question1 ActionController::UrlGenerationError: No route matches {:id=>nil} missing required keys: [: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)>'
Can anyone explain why this is happening and what I can do about it?
Edit - 12/9/13
I raised an error in the method using the better_errors gem in order to attempt reproduce the nil, as Mikhail suggested in the comments. I never got the nil in the app itself - it seems to only show up in rspec testing. Here are the results I got:
>> @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>"
Edit - 12/10/13
Here is the rspec code that sets @answer1:
before :each do
@question1 = create(:question, :id => 99)
@answer1 = create(:answer, :question_id => 99)
sign_in_user(:admin)
end
And the factory:
FactoryGirl.define do
factory :answer do
body { Faker::Lorem.characters(150) }
user_id { 1 }
question_id { 1 }
end
end