Integrate Shrine Images Into Avo Admin for Ruby on Rails

Working on a little Ruby on Rails side project for the first time in a long time, I learned about Avo Admin, which is a super-quick way to provide administrative management of your model data sets. If you had previously used (like me) Active Admin or similar, you'll be shocked at how good Avo looks & works.

Avo leverages ActiveStorage for file uploads and does not natively support third-party solutions like Shrine. However, I did see a closed Github issue that touches on this topic and the reccomendation was to use a custom field to approach this integration. A bit leery of going down a rabbit hole, I took a peek at the documentation for custom fields and figured I could fail pretty fast at least.

Well the good news is, I didn't fail! In fact, it was super fast to do this integration with Avo and Shrine, so much so I figured a blog post for the Internet searchers among us may be of merit. Caveat emptor that this may be an ugly approach - I have no idea - but it was quick & effective, so?

With the following I am able to:

  • Create a new post with an image attached
  • View the post with the image showing
  • Edit the post and select a different image
  • Cache the original image data during an edit to "restore" if needed
  • I also show an existing filename to help make clear when a file is there already
To be clear, the "flow" here is for Shrine purposes, so there's code here that is not necessary to use, but just an example of what I am doing. Hopefully it saves someone time and also prevents people from not using Avo for a small integration gap by seeing how easily extensible it is for your other Gems.

Execute rails generate avo:field shrine_logo

Edit app/avo/fields/shrine_logo_field.rb

class ShrineLogoField < Avo::Fields::BaseField

  attr_reader :logo

  include ImageUploader.Attachment(:logo)

  def initialize(name, **args, &block)

    super(name, **args, &block)

    @logo = args[:logo] || nil

  end

end

Edit app/components/avo/fields/shrine_logo_field/edit_component.html.erb

<%= field_wrapper **field_wrapper_args do %>

  <%= @form.hidden_field :logo, value: @form.object.cached_logo_data %>

  <%= @form.file_field @field.id,class: classes("w-full") %>

  <%= "#{@field.logo ? "Current: " +  @field.value.original_filename : ""}" %>

<% end %>


Edit app/components/avo/fields/shrine_logo_field/show_component.html.erb

<%= field_wrapper **field_wrapper_args do %>

  <%= image_tag @field.value.download_url %>

<% end %>