Generating Devise Controllers - Rails Devise
There are many commands that devise
provides..
rails generate devise:install
- will createconfig/devise.rb
rails generate devise User
- will createdb/migration-file-for-user-model
which commented code,which you can uncomment,if you need other modules..such asconfirmable
,omniauth
etcrails generate devise:views
- will create all views in thedevise
folder withapp/views/devise/sessions
,app/views/devise/confirmations
,registrations
etc folder and its views respectively.rails generate devise:views users
- will create folder ofapp/views/users/passwords/
,app/views/users/confirmations
..etc instead ofdevise
folder above.rails generate devise:controllers
- will create allcontrollers
..similar to above...here it will createapp/controllers/devise/sessions_controller.rb
with default commented code,which you need to edit else leave it as it is for basic authentication.Moreover,you can also addusers
scope in the end,to generate controllers incontrollers/users/
and notcontrollers/devise/
You may also go through this good devise tutorial ..
Hope it helps.
How to generate Registration controller of devise gem
just create the controller manually and make it inherit from Devise. For example:
class Users::RegistrationsController < Devise::RegistrationsController
# Override the action you want here.
end
This controller should live in app/controllers/users/registrations_controller.rb
And mention it in your routes.
devise_for :users, controllers: { registrations: "users/registrations" }
And if you want to only generate it by command than you need to add device gem from master branch because that generator is present on that branch.
gem 'devise', git: 'https://github.com/plataformatec/devise'
As mention on github_issue
How do you access Devise controllers?
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' }
Custom devise registration
This is because you create custom path for user registration, but still use default devise
controller inheritance on call super
that use default routes helper in some inner functions.
The simplest way to fix it - use devise instead of create your own routes
Remove that
devise_scope :user do
post 'sign_up', to: 'users/registrations#create'
end
And change devise_for
devise_for :users, controllers: {
registrations: 'users/registrations'
}
Rails Generate Devise:Controllers not Working
SOLVED
I've just created the controller manually and make it inherit from Devise. For example:
class Users::RegistrationsController < Devise::RegistrationsController
# Override the action you want here.
end
This controller should live in app/controllers/users/registrations_controller.rb. If you have any other scope just go with app/controllers/scope/registrations_controller.rb. For example if you have an admin scope it would be app/controllers/admins/registrations_controller.rb.
Best.
UPDATE
Following the comment from blushrt, I forgot to mention that it is important to modify config/routes.rb to make Devise use the created controller for the specific resource. For example, for users, you should put in your config/routes.rb:
devise_for :users, controllers: { registrations: "users/registrations" }
That's it. Best.
generated Devise Controllers are empty
The generated controller is meant to override the default behavior by removing super
from the action. You can anyway copy and paste the actual code and play around with it. It's available on Github.
You can check the whole source code by following this link, https://github.com/plataformatec/devise
The actual code for Devise::RegistrationsController
is,
class Devise::RegistrationsController < DeviseController
prepend_before_action :require_no_authentication, only: [:new, :create, :cancel]
prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy]
prepend_before_action :set_minimum_password_length, only: [:new, :edit]
# GET /resource/sign_up
def new
build_resource({})
yield resource if block_given?
respond_with resource
end
# POST /resource
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
end
# GET /resource/edit
def edit
render :edit
end
# PUT /resource
# We need to use a copy of the resource because we don't want to change
# the current user in place.
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
resource_updated = update_resource(resource, account_update_params)
yield resource if block_given?
if resource_updated
if is_flashing_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
set_flash_message :notice, flash_key
end
bypass_sign_in resource, scope: resource_name
respond_with resource, location: after_update_path_for(resource)
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
end
# DELETE /resource
def destroy
resource.destroy
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message! :notice, :destroyed
yield resource if block_given?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
def cancel
expire_data_after_sign_in!
redirect_to new_registration_path(resource_name)
end
protected
def update_needs_confirmation?(resource, previous)
resource.respond_to?(:pending_reconfirmation?) &&
resource.pending_reconfirmation? &&
previous != resource.unconfirmed_email
end
# By default we want to require a password checks on update.
# You can overwrite this method in your own RegistrationsController.
def update_resource(resource, params)
resource.update_with_password(params)
end
# Build a devise resource passing in the session. Useful to move
# temporary session data to the newly created user.
def build_resource(hash=nil)
self.resource = resource_class.new_with_session(hash || {}, session)
end
# Signs in a user on sign up. You can overwrite this method in your own
# RegistrationsController.
def sign_up(resource_name, resource)
sign_in(resource_name, resource)
end
# The path used after sign up. You need to overwrite this method
# in your own RegistrationsController.
def after_sign_up_path_for(resource)
after_sign_in_path_for(resource)
end
# The path used after sign up for inactive accounts. You need to overwrite
# this method in your own RegistrationsController.
def after_inactive_sign_up_path_for(resource)
scope = Devise::Mapping.find_scope!(resource)
router_name = Devise.mappings[scope].router_name
context = router_name ? send(router_name) : self
context.respond_to?(:root_path) ? context.root_path : "/"
end
# The default url to be used after updating a resource. You need to overwrite
# this method in your own RegistrationsController.
def after_update_path_for(resource)
signed_in_root_path(resource)
end
# Authenticates the current scope and gets the current resource from the session.
def authenticate_scope!
send(:"authenticate_#{resource_name}!", force: true)
self.resource = send(:"current_#{resource_name}")
end
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
end
def account_update_params
devise_parameter_sanitizer.sanitize(:account_update)
end
def translation_scope
'devise.registrations'
end
end
you can get that here, https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb
Hope that helps!
Customizing devise controller
I think you need to be overriding the registrations controller:
devise_for :users, :controllers => {:registrations => "registrations"}
Then the controller:
controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def create
build_resource(sign_up_params)
admin_user = User.find_by_role(User::admin_role)
if admin_user.nil?
resource.role = User::admin_role
else
resource.role = User::default_role
end
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_with resource
end
end
end
how to create users_controller.rb with devise?
You can generate the devise
controllers using its generate command:
rails generate devise:controllers [scope]
The scope
means which folder you want to create it, like if it is for users then you can give users as scope which will generate the controller in app/controllers/users/
.
You will need to specify this in routes so that rails uses your controllers:
devise_for :users, controllers: { registrations: "users/registrations" }
If you need a controller named users_controller
then you can generate it using:
rails g controller users
But it will not connect with devise
. All the actions (new
, create
, update
, edit
) of User
are handled in registrations_controller
by devise. So you can always override them if that is what required by you. So it will call your custom code instead of the default code.
If you create your own users_controller
it will be normal rails controller. Just define routes for it and create the views inside the users folder it will work.
More info you can find in devise wiki:
https://github.com/plataformatec/devise#configuring-controllers
Hope this helps.
Devise Invitable controller seems not to be reached?
The problem is in your routes since an invitation is not an session.
If you changes sessions to invitations in your routes then it will hit the users/invitations controller.
# routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
invitations: 'users/invitations'
}
end
Related Topics
Ruby: Automatically Wrapping Methods in Event Triggers
Run Ruby Script That Is Stored on Internet
Ruby: Looking for Ruby-Embeddable Interpreter or Scripting Language
Split Float into Integer and Decimals in Ruby
How to Speed Up Ruby/Rake Task
Bundler::Rubyversionmismatch: Your Ruby Version Is 1.9.3, But Your Gemfile Specified 2.0.0
Calling Ruby Method Without Instantiating Class
Error When Starting Sinatra: "Tried to Create Proc Object Without a Block"
Error When Trying to Create Heroku App on Windows
Ruby 1.9 Ramaze App Failing with "Illegal Instruction"
Copy One Slide from Google Slides into a New Presentation Using API
Ruby Gem Cucumber Ssl Error and Gem Sources
"/#Action" Route in Routes.Rb in Ruby on Rails
Return True Only If All Values Evaluate to True in Ruby
Why Should You Avoid the Then Keyword in Ruby
Bundler: Not Executable: Script/Delayed_Job