WilliamZang WilliamZang - 2 months ago 38
Ruby Question

Can I have a flash message in active admin when destroy failed?

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?

Answer

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