In my app, some resources cannot be destroyed. So I wrote my model like this:
before_destroy :destroy_check
def destroy_check
if some_reason?
errors.add(:base, 'cannot destroy this resource!')
end
errors.blank?
end
Then, when I click destroy button in ActiveAdmin, there is nothing to show: no error, no message, and the record is not really destroyed. How can I show an error message when destroy fails?
First use your model's before_destroy
callback to check if the record can be destroyed (here if a student is signed in):
class Student < ActiveRecord::Base
before_destroy :before_destroy_check_for_groups
def before_destroy_check_for_groups
if StudentInGroup.exists?(student_id: self.id)
errors.add(:base, I18n.t('app.student_signed_in'))
return false
end
end
end
It's common and easy and you do it for each model you want.
And here is a trick.
You may apply a general patch for all Active Admin resources to pass your model's error message to the user as a ResourceController
's callback. It's the check_model_errors
method below. And this method has to be registered as a callback during execution of each resource's ActiveAdmin.register
method call (see the patched run_registration_block
).
You may simply paste the code below to a new file (of any name) to the config/initializers
folder of your app (or any other folder which is initialized upon app startup). I put it as config/initializers/active_admin_patches.rb
.
class ActiveAdmin::ResourceController
def check_model_errors(object)
return unless object.errors.any?
flash[:error] ||= []
flash[:error].concat(object.errors.full_messages)
end
end
class ActiveAdmin::ResourceDSL
alias_method :old_run_registration_block, :run_registration_block
def run_registration_block(&block)
old_run_registration_block(&block)
instance_exec { after_destroy :check_model_errors }
end
end
I found this can be accomplished within ActiveAdmin through I18n translations and customizing the Responders' Interpolation Options in the controller.
Adding the method #interpolation_options to ActiveAdmin::BaseController in an initializier:
# config/initializers/active_admin.rb
class ActiveAdmin::BaseController
private
def interpolation_options
options = {}
options[:resource_errors] =
if resource && resource.errors.any?
"#{resource.errors.full_messages.to_sentence}."
else
""
end
options
end
end
Then overriding the translation for the destroy alert message in the locale file:
# config/locales/en.yml
en:
flash:
actions:
destroy:
alert: "%{resource_name} could not be destroyed. %{resource_errors}"
if you want to be a resource that has not been removed from the active admin:
ActiveAdmin.register SomeModel do
controller do
def destroy
flash[:notice] = 'Cant delete this!'
redirect_to :back
end
end
end
or delete actions:
ActiveAdmin.register SomeModel do
actions :all, except: [:destroy]
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With