uninitialized constant DeviseController - ruby-on-rails

I am getting uninitialized constant DeviseController which I explicitly require the Devise gem in Rails project rather than using Bundle.require in application.rb
I have the following in application_controller.rb:
require 'devise'
class ApplicationController < ActionController::Base
include Devise::Controllers::Helpers
before_action :configure_permitted_parameters, if: :devise_controller?
But devise_controller? invokes ::DeviseController and for some reason it is not defined. What is going on here?

The use of require in a Rails app is a red flag. It should rarely be used unless you create your own functionality outside of the scope of your MVC (which would usually be placed in the lib directory)...
Assuming you have installed devise...just remove your require and include statements...
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
end
And all should be well if you have a private method named configure_permitted_parameters ie...(with your appropriate custom attributes and action)
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
end

Related

Skip policies from all controller actions of pundit in existing project rails

I am using existing rails application, where we currently use devise for authentication and Pundit for authorization. My requirement is to skip all policies scope authorization for all action in this existing rails application. How Can I do this?
I have tried below code but not worked:-
class ApplicationController < ActionController::Base
include Pundit
protect_from_forgery with: :exception
before_action :authenticate_user!, :set_default_timezone#, :modify_search_params
before_action :set_current_user
skip_after_action :verify_policy_scoped
#.....
end
Thanks in advance :)
Pundit provides skip_authorization to skip his authorization. Executing it before all actions of the controller will make it work for your requirement.
class ApplicationController < ActionController::Base
# ...
before_action :skip_all_authorization
private
def skip_all_authorization
skip_authorization
end
# ...
end
You need to skip both action authorization with an object (which are called by using authorize(object) and with a policy scope (called with policy_scope).
You can skip the hooks on your base class:
skip_after_action :verify_policy_scoped
skip_after_action :verify_authorized
Or just add another hook to skip them on your controller (my preferred approach)
after_action :skip_all_authorization
private
def skip_all_authorization
skip_policy_scope
skip_authorization
end
But by the way, you shouldn't need this unless you're ensuring the policy is called by adding the appropriate hooks.

alias_method': undefined method `current_user'

Hi i tried to implement forest_admin gem in rails 5 application
When i generate install with this command
rails g forest_liana:install <ENVIRONMENT SECRET>
The logs are alias_method': undefined method current_user' for classApplicationController' (NameError)
My aplication Controller
class ApplicationController < ActionController::Base
skip_before_action :verify_authenticity_token
before_action :session_expirada, unless: :devise_controller?
before_action :set_attr_to_current_user, unless: :devise_controller?
layout :layout_by_resource
alias_method :devise_current_user, :current_user
include RedirectFromEmail
# Pundi Authorization filtros
include Pundit
#after_action :verify_authorized, unless: :devise_controller? , #except: :index
#to catch message error Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
end
What happend?
You are trying to alias the method ":devise_current_user" to ":current_user". IN your controller current_user is not defined. If you define current_user in your controller(see below) then you will not get this error.
def current_user
#logic to get a handle on current user goes here
end
Remove alias and just use regular devise current_user which is included by default

How devise methods are available in ApplicationController.rb?

Is ApplicationController inherits from DeviseController?
Otherwise how devise methods are available in ApplicationController.
ApplicationController inherits from ActionController::Base, which
defines a number of helpful methods.
ref
Devise::Controller has a several modules that's hooked up in to ActionController on_load.
For example the Devise::Controller::Helpers module defines and loads helpers below:
# Generated methods:
# authenticate_user! # Signs user in or redirect
# authenticate_admin! # Signs admin in or redirect
# user_signed_in? # Checks whether there is a user signed in or not
# admin_signed_in? # Checks whether there is an admin signed in or not
# current_user # Current signed in user
# current_admin # Current signed in admin
# user_session # Session data available only to the user scope
# admin_session # Session data available only to the admin scope
#
# Use:
# before_action :authenticate_user! # Tell devise to use :user map
# before_action :authenticate_admin! # Tell devise to use :admin map
ApplicationController doesn't inherit from DeviceController. ApplicationController inherits from ActionController::Base. In ApplicationController the method you talking about configure_permitted_parameters is used with before_filter which is callback.
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :password, :remember_me) }
end
No , Application Controller doesn't inherits from Devise controller.It is the base.To use devise methods in it, you can use the below:
before_filter :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) << [:first_name, :last_name, :is_active]
devise_parameter_sanitizer.for(:sign_in) << [:user_name]
devise_parameter_sanitizer.for(:sign_up) << [:first_name, :last_name,:username,:is_active]
end
def after_sign_in_path_for(resource)
"some path"
end
No, ApplicationController is the base, like the name, is the controller for the all application.
ApplicationController is extended from DeviseController.

Namespaces and inheritance in rails

I have an engine called Admin and a few controllers.
# admin/app/controllers/admin/application_controller.rb
module Admin
class ApplicationController < ActionController::Base
end
end
# admin/app/controllers/admin/foo_controller.rb
module Admin
class CardsController < ApplicationController
end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
If I visit my main app and THEN /admin the CardsController inherits from ApplicationController NOT Admin::ApplicationController. If I first visit /admin and then the main app it works.
I guess that when we first visit the main app the constant ApplicationController is created, which is then found and used when visiting /admin instead of loading Admin::ApplicationController.
How can one avoid this issue?
You'll have to be specific about which class you are inheriting from:
module Admin
class CardsController < Admin::ApplicationController
# ...
end
end

Devise throwing exception when attempting to add parameter to sanitizer

I am following the instructions here in order to add two parameters to my sign up / registration form in a Ruby on Rails + devise based application: http://devise.plataformatec.com.br/#getting-started/strong-parameters
My controller is straight forward:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
before_filter :authenticate_user!
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end
The error I'm getting is the following:
NoMethodError in Devise::SessionsController#new
undefined method `<<' for {}:ActionController::Parameters
Am I using the wrong version of Devise or something? I have gem 'devise', :git => 'https://github.com/plataformatec/devise', :branch => 'v3.0' specified in my Gemfile, nothing else is out of the ordinary.
This feature requires Devise 3.1.0.rc according to an issue opened on the Devise repo.

Resources