Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"request" is nil within DeviseController when subclassing a Devise controller and using scoped views #1859

Closed
atasay opened this issue May 17, 2012 · 5 comments

Comments

@atasay
Copy link

atasay commented May 17, 2012

We have a Github repo reproducing this issue:

https://github.com/atasay/devise-issue

If you run the tests by running the default rake task, you will see the error we're getting.

This is the exception:

  1) Error:
test_index(ErrorReproducerControllerTest):
NoMethodError: undefined method `env' for nil:NilClass
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/devise-2.0.4/app/controllers/devise_controller.rb:38:in `devise_mapping'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/devise-2.0.4/app/controllers/devise_controller.rb:159:in `_prefixes'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/actionpack-3.2.3/lib/abstract_controller/view_paths.rb:45:in `lookup_context'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/actionpack-3.2.3/lib/abstract_controller/view_paths.rb:15:in `rescue in formats='
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/actionpack-3.2.3/lib/abstract_controller/view_paths.rb:13:in `formats='
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/actionpack-3.2.3/lib/action_controller/test_case.rb:442:in `process'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/devise-2.0.4/lib/devise/test_helpers.rb:19:in `block in process'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/devise-2.0.4/lib/devise/test_helpers.rb:71:in `catch'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/devise-2.0.4/lib/devise/test_helpers.rb:71:in `_catch_warden'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/devise-2.0.4/lib/devise/test_helpers.rb:19:in `process'
    /Users/atasay/.rvm/gems/ruby-1.9.3-p125/gems/actionpack-3.2.3/lib/action_controller/test_case.rb:385:in `post'
    /Users/atasay/Desktop/cmondevise/test/controllers/error_reproducer_controller_test.rb:13:in `test_index'

At the top of the stack trace, it says the error is coming from devise_controller.rb:38, which looks like this:

  # Attempt to find the mapped route for devise based on request path
  def devise_mapping
    @devise_mapping ||= request.env["devise.mapping"]
  end

So request is actually nil here. And this is within DeviseController while calling post :create.

This is the full test:

  def test_index
    user = User.create :email => "foo@example.com", :password => "password", :password_confirmation => "password"
    sign_in user

    request.env["devise.mapping"] = Devise.mappings[:user]

    post :create  # <------------   This is where the error occurs
    assert_response :success
  end

This is on Devise 2.1.0 and Rails 3.2.3 but we first noticed the issue with Devise 2.0.4.

Thanks in advance for any suggestions.

@josevalim
Copy link
Contributor

Thanks for the detailed report, we will take a look.

@atasay
Copy link
Author

atasay commented May 17, 2012

I should also mention that the scoped_views config option directly causes the issue. When setting it to false, the error goes away.

@kigster
Copy link

kigster commented May 24, 2012

I have some additional information on this bug.

I tracked it down to the order of instance variables assigned in this file, particular the order of @controller.formats= and @controller.request=

~/.rvm/gems/ruby-1.9.3-p194@global/gems/actionpack-3.2.3/lib/action_controller/test_case.rb:444:in `process'

This process() method has an assignment:

@controller.formats = nil 

which ends up calling into ActionView, and eventually Devise to figure out whether to use scoped views or not (and explodes because request is undefined). Request is undefined because the line

@controller.request = @request

happens after the @controller.formats= call. Once I moved @controller.request = @request before the formats assignment, Devise no longer explodes.

In summary, it looks like in the context of functional controller tests, Devise relies on request object being setup to determine supported formats of the controller, but it can not rely on the request object yet because it wasn't assigned.

I am not clear whether it's a Devise issue, or ActionSupport issue, but it is very surprising that it hasn't gotten caught before. Basically any controller tests with scoped views with Devise would be broken.

@josevalim
Copy link
Contributor

Thanks for the detailed report. I have added a fix for Devise master, can you please check it works for you? Thanks!

@kigster
Copy link

kigster commented May 26, 2012

Seems to be fixed! We are now getting a proper result from posting to an action. Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants