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

Undefined method users_url in SessionController #1350

Closed
mathcolo opened this issue Sep 27, 2011 · 25 comments
Closed

Undefined method users_url in SessionController #1350

mathcolo opened this issue Sep 27, 2011 · 25 comments

Comments

@mathcolo
Copy link

I'm using the master branch of Devise in my project and when I use a REST tester to POST to /users/sign_in.json, I get a NoMethodError:

undefined method `users_url' for #<Devise::SessionsController:0x007fef858a55a8>

Here is the full trace:

actionpack (3.1.0) lib/action_dispatch/routing/polymorphic_routes.rb:127:in 'polymorphic_url'
actionpack (3.1.0) lib/action_dispatch/routing/url_for.rb:145:in 'url_for'
actionpack (3.1.0) lib/action_controller/metal/rendering.rb:60:in '_process_options'
actionpack (3.1.0) lib/action_controller/metal/streaming.rb:233:in '_process_options'
actionpack (3.1.0) lib/action_controller/metal/renderers.rb:36:in 'block in _handle_render_options'
actionpack (3.1.0) lib/action_controller/metal/renderers.rb:34:in 'each'
actionpack (3.1.0) lib/action_controller/metal/renderers.rb:34:in '_handle_render_options'
actionpack (3.1.0) lib/action_controller/metal/renderers.rb:30:in 'render_to_body'
actionpack (3.1.0) lib/action_controller/metal/compatibility.rb:43:in 'render_to_body'
actionpack (3.1.0) lib/abstract_controller/rendering.rb:99:in 'render'
actionpack (3.1.0) lib/action_controller/metal/rendering.rb:16:in 'render'
actionpack (3.1.0) lib/action_controller/metal/instrumentation.rb:40:in 'block (2 levels) in render'
activesupport (3.1.0) lib/active_support/core_ext/benchmark.rb:5:in 'block in ms'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/benchmark.rb:310:in 'realtime'
activesupport (3.1.0) lib/active_support/core_ext/benchmark.rb:5:in 'ms'
actionpack (3.1.0) lib/action_controller/metal/instrumentation.rb:40:in 'block in render'
actionpack (3.1.0) lib/action_controller/metal/instrumentation.rb:78:in 'cleanup_view_runtime'
activerecord (3.1.0) lib/active_record/railties/controller_runtime.rb:24:in 'cleanup_view_runtime'
actionpack (3.1.0) lib/action_controller/metal/instrumentation.rb:39:in 'render'
actionpack (3.1.0) lib/action_controller/metal/responder.rb:252:in 'display'
actionpack (3.1.0) lib/action_controller/metal/responder.rb:204:in 'api_behavior'
actionpack (3.1.0) lib/action_controller/metal/responder.rb:181:in 'rescue in to_format'
actionpack (3.1.0) lib/action_controller/metal/responder.rb:175:in 'to_format'
actionpack (3.1.0) lib/action_controller/metal/responder.rb:153:in 'respond'
actionpack (3.1.0) lib/action_controller/metal/responder.rb:146:in 'call'
actionpack (3.1.0) lib/action_controller/metal/mime_responds.rb:238:in 'respond_with'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/lib/devise/controllers/internal_helpers.rb:142:in 'respond_with_navigational'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/app/controllers/devise/sessions_controller.rb:10:in 'new'
actionpack (3.1.0) lib/action_controller/metal/implicit_render.rb:4:in 'send_action'
actionpack (3.1.0) lib/abstract_controller/base.rb:167:in 'process_action'
actionpack (3.1.0) lib/action_controller/metal/rendering.rb:10:in 'process_action'
actionpack (3.1.0) lib/abstract_controller/callbacks.rb:18:in 'block in process_action'
activesupport (3.1.0) lib/active_support/callbacks.rb:434:in '_run__2626332037988282076__process_action__4293483815377010594__callbacks'
activesupport (3.1.0) lib/active_support/callbacks.rb:386:in '_run_process_action_callbacks'
activesupport (3.1.0) lib/active_support/callbacks.rb:81:in 'run_callbacks'
actionpack (3.1.0) lib/abstract_controller/callbacks.rb:17:in 'process_action'
actionpack (3.1.0) lib/action_controller/metal/rescue.rb:17:in 'process_action'
actionpack (3.1.0) lib/action_controller/metal/instrumentation.rb:30:in 'block in process_action'
activesupport (3.1.0) lib/active_support/notifications.rb:53:in 'block in instrument'
activesupport (3.1.0) lib/active_support/notifications/instrumenter.rb:21:in 'instrument'
activesupport (3.1.0) lib/active_support/notifications.rb:53:in 'instrument'
actionpack (3.1.0) lib/action_controller/metal/instrumentation.rb:29:in 'process_action'
actionpack (3.1.0) lib/action_controller/metal/params_wrapper.rb:201:in 'process_action'
activerecord (3.1.0) lib/active_record/railties/controller_runtime.rb:18:in 'process_action'
actionpack (3.1.0) lib/abstract_controller/base.rb:121:in 'process'
actionpack (3.1.0) lib/abstract_controller/rendering.rb:45:in 'process'
actionpack (3.1.0) lib/action_controller/metal.rb:193:in 'dispatch'
actionpack (3.1.0) lib/action_controller/metal/rack_delegation.rb:14:in 'dispatch'
actionpack (3.1.0) lib/action_controller/metal.rb:236:in 'block in action'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/lib/devise/failure_app.rb:45:in 'call'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/lib/devise/failure_app.rb:45:in 'recall'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/lib/devise/failure_app.rb:29:in 'respond'
actionpack (3.1.0) lib/abstract_controller/base.rb:167:in 'process_action'
actionpack (3.1.0) lib/abstract_controller/base.rb:121:in 'process'
actionpack (3.1.0) lib/action_controller/metal.rb:193:in 'dispatch'
actionpack (3.1.0) lib/action_controller/metal/rack_delegation.rb:14:in 'dispatch'
actionpack (3.1.0) lib/action_controller/metal.rb:236:in 'block in action'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/lib/devise/failure_app.rb:18:in 'call'
~/.rvm/gems/ruby-1.9.2-p290/bundler/gems/devise-15b76e93d13d/lib/devise/failure_app.rb:18:in 'call'
warden (1.0.5) lib/warden/manager.rb:118:in 'call_failure_app'
warden (1.0.5) lib/warden/manager.rb:104:in 'process_unauthenticated'
warden (1.0.5) lib/warden/manager.rb:47:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/best_standards_support.rb:17:in 'call'
rack (1.3.3) lib/rack/etag.rb:23:in 'call'
rack (1.3.3) lib/rack/conditionalget.rb:35:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/head.rb:14:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/params_parser.rb:21:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/flash.rb:243:in 'call'
rack (1.3.3) lib/rack/session/abstract/id.rb:195:in 'context'
rack (1.3.3) lib/rack/session/abstract/id.rb:190:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/cookies.rb:326:in 'call'
activerecord (3.1.0) lib/active_record/query_cache.rb:62:in 'call'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:477:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/callbacks.rb:29:in 'block in call'
activesupport (3.1.0) lib/active_support/callbacks.rb:392:in '_run_call_callbacks'
activesupport (3.1.0) lib/active_support/callbacks.rb:81:in 'run_callbacks'
actionpack (3.1.0) lib/action_dispatch/middleware/callbacks.rb:28:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/reloader.rb:68:in 'call'
rack (1.3.3) lib/rack/sendfile.rb:101:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/remote_ip.rb:48:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/show_exceptions.rb:47:in 'call'
railties (3.1.0) lib/rails/rack/logger.rb:13:in 'call'
rack (1.3.3) lib/rack/methodoverride.rb:24:in 'call'
rack (1.3.3) lib/rack/runtime.rb:17:in 'call'
activesupport (3.1.0) lib/active_support/cache/strategy/local_cache.rb:72:in 'call'
rack (1.3.3) lib/rack/lock.rb:15:in 'call'
actionpack (3.1.0) lib/action_dispatch/middleware/static.rb:53:in 'call'
railties (3.1.0) lib/rails/engine.rb:455:in 'call'
railties (3.1.0) lib/rails/rack/content_length.rb:16:in 'call'
railties (3.1.0) lib/rails/rack/log_tailer.rb:14:in 'call'
rack (1.3.3) lib/rack/handler/webrick.rb:59:in 'service'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in 'service'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in 'run'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in 'block in start_thread'

How do I/we remedy this bug? Thanks!

@josevalim
Copy link
Contributor

Could you please provide a failing test case to Devise code base? That would help us a lot to understand and fix the issue.

@mathcolo
Copy link
Author

I'm actually a relatively new Rails developer and I haven't yet gotten so far as to develop test cases for my project. I'm sure that doesn't help...is there anything else I could provide to help locate the source of the problem?

@josevalim
Copy link
Contributor

Can you provide a sample application that reproduces this error and push it to Github and show us the rest tester that you are using?

btw, have you added :json to navigational formats in your devise initializer?

@mathcolo
Copy link
Author

Okay, I was in the process of creating a sample application to show the bug, but when I checked the routing, I noticed that in my sample application the Devise installation left "resources :users" in after the devise_for line. I put that line back in my original project, and JSON sign_in worked properly. So the moral of the story is that the resources line in the routes file must be left in (just in case any other Rails developers come across this issue).

Thanks so much for your quick responses, this is a great project!

@chrisnicola
Copy link

@josevalim just ran into this myself today. I'm not sure why the resources :users is needed for this to not throw an error when performing an AJAX call with JSON.

Just to clarify our routes look like this:

  devise_for :users,
    controllers: {
    registrations:  "users/registrations",
    confirmations:  "users/confirmations",
    sessions:       "users/sessions",
    passwords:      "users/passwords",
  }, :path_names => {:sign_in => "login", :sign_out => "logout"}

It works fine for regular form logins and it even works for JSON as long as the login is successful. But if I submit an empty form or a bad username or password I get the undefined method 'user_url' error mentioned above.

As @mathcolo mentioned, it does work when I added resources :users after that block. But of course that leads to routes getting defined like /users (when I have no UsersController). It's odd.

@josevalim
Copy link
Contributor

@LucisFerre we still need a way to reproduce the issue. otherwise there is nothing we can do. :S

@davidw
Copy link

davidw commented Nov 16, 2012

I do not know if it's the same issue, but I adding resources :users helped my code as well to make my rspec tests pass. Here's my situation: upgrading from 1.5.3 to 2.1.2, with a User model, and the following custom code:

devise_for :users, :controllers => {:sessions => :sessions,
  :registrations => :registrations, :confirmations => :confirmations}
devise_scope(:user) do
  get 'logout' => 'devise/sessions#destroy'
  get 'users/info', :to => 'registrations#info'
end

And corresponding controllers that override a few things from Devise. In my controllers, as part of the upgrade, I tried to copy anything new that made sense. For instance:

-      respond_with_navigational(resource) { render_with_scope :new }
+      respond_with resource

Previously, I did not have resources :users, and things failed with the undefined method users_url. There are a slew of other errors from the upgrade too, but one at a time...

@davidw
Copy link

davidw commented Nov 21, 2012

I created a github project that causes

undefined method `users_url' for #<RegistrationsController:0xa79b148>

Perhaps there's a bug in my code, but it's really pretty simple. Here's the repository of a very simple Rails app with an rspec test that causes things to blow up:

https://github.com/davidw/devise-rspec-registration-create-bug

@josevalim josevalim reopened this Nov 21, 2012
@davidw
Copy link

davidw commented Nov 21, 2012

I pushed another update to my mini project that does a STDERR.puts resource.errors, and it shows that it has no 'messages', even though it's clearly not an ok user.

@davidw
Copy link

davidw commented Nov 22, 2012

More data: I tried adding this to the user.rb file in my example project:

before_validation do
  STDERR.puts "BEFORE VALIDATION THINGY"
end

It does not get called in the tests, but gets called when accessing things 'normally', in a browser.

Something else that's strange, is, if in the create method in RegistrationsController, I call save! instead of save, it errors out correctly.

@davidw
Copy link

davidw commented Nov 22, 2012

If, in Devise::RegistrationsController#build_resource, I call self.resource.valid?, everything works as expected: there are messages in resource.errors, and response.should render_template("new") works as well. So... it seems that somehow that is not being triggered by the save?

@davidw
Copy link

davidw commented Nov 22, 2012

Argh... never mind, I'm a moron. This is what's causing the problem.

    User.any_instance.stub(:save).and_return(false)

It used to work and now it does not, for whatever reason, but it's clearly what's causing things to go haywire. Argh! anyway, I think this can be closed.

@jonathanroy
Copy link

I have the same issue and no solution. Can this issue be re-opened?

@aminhotob
Copy link

I had the same error when overriding RegistrationsController, but it works when i add error to resource before respond

def update if bool .......... else self.resource.errors.add(:current_password, (params[:user][:current_password]).blank? ? :blank : :invalid) clean_up_passwords resource respond_with self.resource end end

this self.resource.errors.add(:current_password, (params[:user][:current_password]).blank? ? :blank : :invalid) fix the problem with me

@Tuman829
Copy link

I have the same original issue, without "resources :users", I get a "undefined local variable or method `users_path'" error.

@latortuga
Copy link
Contributor

@Tuman829 if you're still having this issue, please open a new issue with your rails version, devise version, a stacktrace, and, if you're feeling motivated, a failing example app or test case. It's possible we won't be able to help you unless you provide one of the last two items but we try to reserve the Github issues for bugs with devise and direct everyone to the mailing list for support. Also keep in mind that if your devise version matches the original issue here, our first advice will be to upgrade to a more recent version as we don't generally push fixes to older releases unless they are security critical.

@Tuman829
Copy link

I am running the newest version of devise, let me see what I can do. I have posted in the mailing list as well.

@ghost
Copy link

ghost commented Apr 3, 2014

If there is some sort of error in the code, this error could be thrown. In my case, I was trying to redirect to previous url after signin and it looks like I had an extra end in my application controller code.

I was commenting out my code one by one and retracted back. Now I don't have this error nor I am able to redirect to previous url. Still trying...

Thanks for all the inputs.

@adampope
Copy link

adampope commented Aug 1, 2014

I had this error, but only when I was trying to deep link in to my app when not logged in. It turned out to be a sneaky little bug, one that's worth remembering. I had overridden after_sign_in_path_for to do different redirects based on my User's state. At the top of that I had

if stored_location_for(resource)
  return stored_location_for(resource)
end

However, when you call stored_location_for it clears the value, so when a value was present the condition was true but then it returned nil, at which point Devise must have fallen back on the default of users_url, which I don't have defined.

I now have

redirect = stored_location_for(resource)
return redirect if redirect.present?

@mib32
Copy link

mib32 commented Jul 9, 2015

This is happening because your implementation of after_sign_in_path_for method returns nil.

@doncadavona
Copy link

It's June 2016 and the error still occurs.

@aponcz
Copy link

aponcz commented Aug 21, 2016

@doncadavona - This should be working fine. Are you redefining after_sign_in_path_for?

What does 'grep -r after_sign_in_path_for app/' return?

@dgreen22
Copy link

@mib32 was my solution.

@serghost
Copy link

My solution was to remove json from config.navigational_formats = ['*/*', :html, :json]

@pmn4
Copy link

pmn4 commented Mar 26, 2020

for me, the solution was to set this config option to true (it had been false 🤷‍♂ )

# config/initializers/devise.rb
# If 401 status code should be returned for AJAX requests. True by default.
config.http_authenticatable_on_xhr = true

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