So I was facing this issue a while ago when I wanted to show an error on Active Admin when the password token is expired. By default devise doesn't show error when the token is expired. check the below devise update code
# PUT /resource/password
def update
self.resource = resource_class.reset_password_by_token(resource_params)
yield resource if block_given?
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
if Devise.sign_in_after_reset_password
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_flashing_format?
sign_in(resource_name, resource)
else
set_flash_message(:notice, :updated_not_active) if is_flashing_format?
end
respond_with resource, location: after_resetting_password_path_for(resource)
else
set_minimum_password_length
respond_with resource
end
end
So as you can see if the condition resource.errors.empty? is false it does not set any errors in the else block.
So one way to solve this is to override the whole method and add flash[:error] in the else block like this
ActiveAdmin::Devise::PasswordsController.class_eval do
def update
self.resource = resource_class.reset_password_by_token(resource_params)
yield resource if block_given?
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
if Devise.sign_in_after_reset_password
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_flashing_format?
sign_in(resource_name, resource)
else
set_flash_message(:notice, :updated_not_active) if is_flashing_format?
end
respond_with resource, location: after_resetting_password_path_for(resource)
else
flash[:error] = resource.errors.full_messages.to_sentence
set_minimum_password_length
respond_with resource
end
end
end
but this is not a very smart way to handle this as I am repeating a lot of the code. so I thought of another DRY way to do this
ActiveAdmin::Devise::PasswordsController.class_eval do
def update
super
if resource.errors.any?
flash[:error] = resource.errors.full_messages.to_sentence
end
end
end
Although this looks fine but it doesn't work as the flash message is shown in the next request.
after a while of searching here and there my eye caught the following code in the devise method
yield resource if block_given?
and here is the solution I came up with.
ActiveAdmin::Devise::PasswordsController.class_eval do
def update
super do |resource|
if resource.errors.any?
flash[:notice] = resource.errors.full_messages.to_sentence
end
end
end
end
Hope it helped :)
# PUT /resource/password
def update
self.resource = resource_class.reset_password_by_token(resource_params)
yield resource if block_given?
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
if Devise.sign_in_after_reset_password
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_flashing_format?
sign_in(resource_name, resource)
else
set_flash_message(:notice, :updated_not_active) if is_flashing_format?
end
respond_with resource, location: after_resetting_password_path_for(resource)
else
set_minimum_password_length
respond_with resource
end
end
So as you can see if the condition resource.errors.empty? is false it does not set any errors in the else block.
So one way to solve this is to override the whole method and add flash[:error] in the else block like this
ActiveAdmin::Devise::PasswordsController.class_eval do
def update
self.resource = resource_class.reset_password_by_token(resource_params)
yield resource if block_given?
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
if Devise.sign_in_after_reset_password
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_flashing_format?
sign_in(resource_name, resource)
else
set_flash_message(:notice, :updated_not_active) if is_flashing_format?
end
respond_with resource, location: after_resetting_password_path_for(resource)
else
flash[:error] = resource.errors.full_messages.to_sentence
set_minimum_password_length
respond_with resource
end
end
end
but this is not a very smart way to handle this as I am repeating a lot of the code. so I thought of another DRY way to do this
ActiveAdmin::Devise::PasswordsController.class_eval do
def update
super
if resource.errors.any?
flash[:error] = resource.errors.full_messages.to_sentence
end
end
end
Although this looks fine but it doesn't work as the flash message is shown in the next request.
after a while of searching here and there my eye caught the following code in the devise method
yield resource if block_given?
and here is the solution I came up with.
ActiveAdmin::Devise::PasswordsController.class_eval do
def update
super do |resource|
if resource.errors.any?
flash[:notice] = resource.errors.full_messages.to_sentence
end
end
end
end
Hope it helped :)