basically I want to have two separate actions for change password and change email instead of just one.
I have updated my routes to point to my new controller which inherits from Devise::RegistrationsController.
My routes.rb:
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get "/users/password" => "registrations#change_password", :as => :change_password
end
My registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def change_password
end
end
My app/views/devise/registrations/change_password.html.erb
<%=debug resource%>
Which gives me nil.
What am I missing here?
Thanks!
In Devise's built-in registrations_controller.rb, there is an authenticate_scope! method that creates the resource object you're looking for. It is executed by a prepend_before_filter, but only for certain methods:
class Devise::RegistrationsController < DeviseController
...
prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]`
So you simply need to tell your custom controller to run that filter on your change_password method:
class RegistrationsController < Devise::RegistrationsController
prepend_before_filter :authenticate_scope!, :only => [:change_password]
def change_password
end
end
class RegistrationsController < Devise::RegistrationsController
def change_password
super
#resource = resource
end
end
app/views/devise/registrations/change_password.html.erb
<%=debug #resource%>
Related
I created a userstamps method to know which user created and edited a data. I have this table Illustrator that I am trying to assign created_by to the current_user id. But when it saves, created_by is nil and don't show any error. When I put raise right before illustrator.save, the #illustrator.created_by is exactly the current_user.id but when I check the value in db, is nil.
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:custom_authenticatable
belongs_to :account
belongs_to :role
cattr_accessor :current_user
validates :email, presence: true, uniqueness: true
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password,
length: { minimum: 6 },
if: -> { new_record? || !password.nil? }
enum gen: { masculino: 1, feminino: 2 }
private
#apenas usuário com role de admim pode logar.
def valid_for_custom_authentication?(password)
#self.role.name == 'admin'
self.role_id === 2
end
end
class ApplicationController < ActionController::Base
before_action :authenticate_user!
helper_method :current_user
private
def current_user=(user)
#current_user = user
end
end
class IllustratorsController < ApplicationController
before_action :authenticate_user!
def new
#illustrator = Illustrator.new
end
def create
#illustrator = Illustrator.new(illustrator_params)
#illustrator.created_by = current_user.id
if #illustrator.save
redirect_to illustrator_path(#illustrator), notice: 'O autor foi criado com sucesso.'
else
render :new
end
end
private
def illustrator_params
params.require(:illustrator).permit(:name, :display_name, :email, :phone, :status, :notes, :created_by)
end
end
Rails.application.routes.draw do
get 'payments/index'
devise_for :users
root to: 'pages#home'
resources :books
resources :authors
resources :publishers
resources :illustrators
resources :plans do
resources :accounts, only: %i[new create] do
end
end
resources :payments, only: %i[index]
resources :accounts, only: %i[index show edit update destroy] do
resources :users, only: %i[new create] do
resources :roles
end
end
resources :users, only: %i[edit update index show destroy]
#API routes
namespace :api do
namespace :v1 do
get 'default/:id', to: 'plans#change_plans'
get 'plans', to: 'plans#index'
get 'plans/id', to: 'plans#show'
get 'accounts', to: 'accounts#return'
post 'users', to: 'users#create'
#resources :users
post '/auth/login', to: 'authentication#login'
get '/*a', to: 'application#not_found'
post 'password/forgot', to: 'users#forgot_password'
end
end
end
If you are using devise, you dont need this part:
helper_method :current_user
private
def current_user=(user)
#current_user = user
end
Where did you even find it? Remove it from your codebase!
With devise you don't need any getter or setter methods.
It can possibly be the reason it's not working for you.
If in application_controller you have the before_action :authenticate_user!, current_user method should work right out of the box!
As well you don't need to add the before_action :authenticate_user! again here
class IllustratorsController < ApplicationController
before_action :authenticate_user!
, because you already made it application-wide in application_controller.
Your create method is good. Try removing the abundancies and it should all work.
You have just setter method in your controller where you are setting current_user
def current_user=(user)
#current_user = user
end
You need to add getter method as well like following so that you can use it in your controller
def current_user
#current_user
end
In ruby there is short cut for this attr_accessor :current_user Ref this
What I need is that when a user goes to '/admin', it redirects to '/admins/sign_in' for the user to sign in.
This is what I did:
# routes.rb
devise_for :admins
namespace :admin do
root to: 'users#index'
end
.
# controllers/admin/base_controller.rb
class Admin::BaseController < ApplicationController
before_action :authenticate_user!
layout 'admin'
end
.
# controllers/admin/users_controller.rb
class Admin::UsersController < Admin::BaseController
def index
end
end
The problem is that when I go to '/admin' it returns me an error:
NoMethodError in Admin::UsersController#index ..
undefined method `authenticate_user!' for Admin::UsersController
How can I make it work?
We have nearly the same setup as you, and it works perfectly:
I think the problem is that you're using devise_for :admins, and yet calling authenticate_user!; it should be authenticate_admin! (as per the Devise docs):
class Admin::BaseController < ApplicationController
before_action :authenticate_admin!
end
class Users::PasswordsController < Devise::PasswordsController
skip_before_filter :require_no_authentication, only: [:edit]
def after_resetting_password_path_for(resource)
completed_reset_path
#super(resource)
end
routes:
devise_for :users, controllers: { passwords: "users/passwords"}
match "completed_reset", to: 'home#completed_reset', via: [:get]
HomeController:
class HomeController < ApplicationController
def index
end
def completed_reset
end
end
When I reset my password, I get redirected to root instead of to completed_reset_path . Why is this happening?
Maybe try:
get 'completed_reset', :to => 'home#completed_reset'
Instead of:
match "completed_reset", to: 'home#completed_reset', via: [:get]
In config/initializers/devise.rb:
Set config.sign_in_after_reset_password = false
I have a Admin::SessionsController who extends from Admin::ApplicationController.
I'm using a before_filter except to the login page, but the server is entering in a loop
I think there`s is something with the except thing, I think that I need to set the namespace or something...
This is the line of before_filte:
before_filter :authenticate_user , :except => { :sessions => :new }
This is my SessionController
class Admin::SessionsController < Admin::ApplicationController
def new
end
end
It might be easiest just to put a skip_before_filter in the Admin:SessionsController
class Admin::SessionsController < Admin::ApplicationController
skip_before_filter :authenticate_user, :only => [:new]
def new
end
end
I'm using Devise as authenticating solution in Rails and I have a cached fragment :recent_users.
I want this fragment to expire when a new user is registered, changed or removed, so I put in my(manually created) users_controller.rb
class UsersController < ApplicationController
cache_sweeper :user_sweeper, :only => [:create, :update, :destroy]
...
But my fragment does not expire when new creates or changes.
My user_sweeper contains basic prescriptions
class UserSweeper < ActionController::Caching::Sweeper
observe User
def after_save(user)
expire_cache(user)
end
def after_destroy(user)
expire_cache(user)
end
private
def expire_cache(user)
expire_fragment :recent_users
end
end
What am I doing wrong?
Problem solved!
I followed this steps and everything works:
$ mkdir app/controllers/users
$ touch app/controllers/users/registrations_controller.rb
In registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
cache_sweeper :user_sweeper, :only => [:create, :update, :destroy]
end
Problem was that Registrations in Devise is a separate controller.
Put this in applications_controller.rb
class ApplicationController < ActionController::Base
cache_sweeper :user_sweeper, :only => [:create, :update, :destroy]
...