With Avo, being a Ruby on Rails engine, we have a few controllers where we "chew up" the request, fetch the data, and display the results. This includes our own ApplicationController.
Over the weekend, one of our customers reported an issue after they updated to Avo 2.17. After a bit of digging I figured that one helper we introduced in the ApplicationController was missing from their setup. Fear came over me; "did we forget to add that helper?", "Was it somehow removed in a merge?", "is this happening to everyone?".
I started digging in. I opened the gem using bundle open avo and checked. We didn't forget about it. It was there.
Hmmm. Weird. I started to think 🤔 "could it be? could they have overriden the ApplicationController class?". Yes they did! They did it ot add a concern that deals with some multitenancy scenario.
# Copied from Avo to `app/controllers/avo/application_controller.rb`
module Avo
class ApplicationController < ::ActionController::Base
include Pagy::Backend
include Avo::ApplicationHelper
include Avo::UrlHelpers
protect_from_forgery with: :exception
around_action :set_avo_locale
before_action :multitenancy_detector
# ... more Avo::ApplicationController methods
def multitenancy_detector
# your logic here
end
end
end
That fixed their business need but introduced a a very fragile piece of code that broke as soon as we updated the application controller.
Fortunately there's a nice way to fix that.
Create a concern that holdes your piece of code.
# app/controllers/concerns/multitenancy.rb
module Multitenancy
extend ActiveSupport::Concern
included do
before_action :multitenancy_detector
end
def multitenancy_detector
# your logic here
end
end
Include it in the controller from the outside
# configuration/initializers/avo.rb
Rails.configuration.to_prepare do
Avo::ApplicationController.include Multitenancy
end
Now, the concern, the multitenancy_detector method, and the before_action are safely included in Avo::ApplicationController.
More on this on our docs about the ApplicationController ✌️
Bonus
If you'd like to add a before_action before all of Avo's before actions, use prepend_before_action instead. That will run that code first and enable you to set an account or do something early on.