Skip to content

Instantly share code, notes, and snippets.

@adrianthedev
Last active April 8, 2023 20:49
Show Gist options
  • Save adrianthedev/230650088d98ee068c3fd90fad337615 to your computer and use it in GitHub Desktop.
Save adrianthedev/230650088d98ee068c3fd90fad337615 to your computer and use it in GitHub Desktop.
Avo tip for Rails tips

Hello there,

I'm Adrian, the author of Avo, and I'm excited to share a neat trick with you today. In this tutorial, I'll be demonstrating how to attach hooks and business logic to Avo's controllers using a Current model.

You may already be familiar with Rails' Current model, which is used to set the current user, multi-tenancy accounts, or other pieces of information. Typically, before_action is used in your ApplicationController to demonstrate how Current works. However, if you attempt to apply the same changes to your app the action will not work in Avo's context. This is because Avo has its own AplicationController.

So how do we apply this behavior inside Avo? Let me walk you through it.

Firstly, we configure the Current model and create the concern that holds the business logic.

# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :account, :user
end

# app/controllers/concerns/authentication.rb
module Authentication
  extend ActiveSupport::Concern

  included do
    before_action :set_current
  end

  def set_current
    Current.user = current_user
    Current.account = user.account
  end
end

Next, we add this concern to Avo's ApplicationController using Rails' to_prepare hook:

# config/initializers/avo.rb
Rails.configuration.to_prepare do
  Avo::ApplicationController.include Authentication
end

With this setup, our Authentication concern will be applied to the Avo::ApplicationController, and it will be executed within Avo's context.

This technique can also be applied to other classes, such as including all helpers inside Avo's field declarations:

# app/avo/concerns/field_extensions.rb
module FieldExtensions
  # Include all helpers
  helper_names = ActionController::Base.all_helpers_from_path Rails.root.join("app", "helpers")
  helpers = ActionController::Base.modules_for_helpers helper_names

  helpers.each do |helper|
    send(:include, helper)
  end
end

# config/initializers/avo.rb
Rails.configuration.to_prepare do
  Avo::Fields::BaseField.include FieldExtensions
end

By following these steps, you can now use your own extensions in your Avo resources. I hope this short tutorial helps you write better Avo resources and ship code faster.

Adrian ✌️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment