After Rails 4 upgrade, view_context is working in app, but failing tests. Why?

958 views Asked by At

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
0

There are 0 answers