Generating Devise Controllers - Rails Devise

Generating Devise Controllers - Rails Devise

There are many commands that devise provides..

  1. rails generate devise:install - will create config/devise.rb
  2. rails generate devise User - will create db/migration-file-for-user-model which commented code,which you can uncomment,if you need other modules..such as confirmable,omniauth etc
  3. rails generate devise:views - will create all views in the devise folder with app/views/devise/sessions,app/views/devise/confirmations,registrations etc folder and its views respectively.
  4. rails generate devise:views users - will create folder of app/views/users/passwords/,app/views/users/confirmations ..etc instead of devise folder above.
  5. rails generate devise:controllers - will create all controllers..similar to above...here it will create app/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 add users scope in the end,to generate controllers in controllers/users/ and not controllers/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



Leave a reply



Submit