How do you access Devise controllers?
Solution 1:
Under the assumption that you want to see these controllers in order to modify or override them, Devise now provides a simple generator which recreates their controllers in your app to make this easy. As per the documentation (which will be most up-to-date):
1) Create your custom controllers using the generator which requires a scope:
console
rails generate devise:controllers [scope]
If you specify users
as the scope, controllers will be created in app/controllers/users/
. And the sessions controller will look like this:
class Users::SessionsController < Devise::SessionsController
# GET /resource/sign_in
# def new
# super
# end
...
end
2) Tell the router to use this controller:
devise_for :users, controllers: { sessions: "users/sessions" }
3) Copy the views from devise/sessions
to users/sessions
. Since the controller was changed, it won't use the default views located in devise/sessions
.
4) Finally, change or extend the desired controller actions.
You can completely override a controller action:
class Users::SessionsController < Devise::SessionsController
def create
# custom sign-in code
end
end
Or you can simply add new behaviour to it:
class Users::SessionsController < Devise::SessionsController
def create
super do |resource|
BackgroundWorker.trigger(resource)
end
end
end
This is useful for triggering background jobs or logging events during certain actions.
Remember that Devise uses flash messages to let users know if sign in was successful or unsuccessful. Devise expects your application to call flash[:notice]
and flash[:alert]
as appropriate. Do not print the entire flash hash, print only specific keys. In some circumstances, Devise adds a :timedout
key to the flash hash, which is not meant for display. Remove this key from the hash if you intend to print the entire hash.
Solution 2:
Devise uses internal controllers, which you can access and subclass in your own code. They are under the Devise
module. For example, to extend the RegistrationsController
:
class MembershipsController < Devise::RegistrationsController
# ...
end
Then all you have to do is configure Devise's routes to use your controller instead:
devise_for :members, :controllers => { :registrations => 'memberships' }
Solution 3:
$ rails generate devise:controllers SCOPE [options]
Options: -c, [--controllers=one two three]
Select specific controllers to generate (confirmations, passwords, registrations, sessions, unlocks, omniauth_callbacks)
Use -c to specify which controller you want to overwrite. If you do not specify a controller, all devise controllers will be created. For example:
rails generate devise:controllers users -c=sessions
This will create a controller class at app/controllers/users/sessions_controller.rb like this:
class Users::ConfirmationsController < Devise::ConfirmationsController
content...
end