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.