Resolving ActiveStorage URL Generation Between Rails and Avo admin gem
Tags: rails, activestorage, avo, gem
Published: 2023-08-15 19:16:49

I've been working on my project [Modatongue](https://modatongue.com) and hit a roadblock with Active Storage. Images were displaying fine in lessons or my main rails application, but not in my Avo admin! 😭


TLDR;
Just change line 3 of your **app/views/active_storage/_blobs.html.erb** to use main_app.url_ 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6q2z1wuocdognzljfxzc.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/guewcri78y2r8lrw81c5.png)

**My Battle with Active Storage (and How I Won!)**
Like I mentioned earlier the Images were displaying fine in my lessons or inside the main rails app, but not in my [Avo](https://avohq.io/) admin or when I logged into my admin interface! 😭

```
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
  <% if blob.representable? %>
    <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
  <% end %>

  <figcaption class="attachment__caption">
    <% if caption = blob.try(:caption) %>
      <%= caption %>
    <% else %>
      <span class="attachment__name"><%= blob.filename %></span>
      <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
    <% end %>
  </figcaption>
</figure>
```

The above code for my blob partial(which is likely going to be your default when you install active storage). This works in Rails views, but not Avo which expects blob objects to respond to to_model. Avo admin cried undefined method 'to_model'. Ugh, why?! 🤯

After a lot of trial and error, I realized Avo uses different helpers. So I tried bypassing them directly with:

`<%= image_tag main_app.url_for(blob) %>`

so now my blob partial will look like:

```
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
  <% if blob.representable? %>
    <%= image_tag main_app.url_for(blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ])) %>
  <% end %>

  <figcaption class="attachment__caption">
    <% if caption = blob.try(:caption) %>
      <%= caption %>
    <% else %>
      <span class="attachment__name"><%= blob.filename %></span>
      <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
    <% end %>
  </figcaption>
</figure>
```


**The Solution**
The key was to bypass both helpers and generate the URL directly from Rails.

This works because main_app references the root Rails application context:

`  <%= image_tag main_app.url_for(blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ])) %>`

Now url_for generates the URL correctly for any ActiveStorage attachment, working identically in both Rails and Avo views.
By leveraging the core Rails URL generation, a single rendering approach can work consistently across any frameworks layered on top of Rails. This keeps view code DRY and avoids compatibility issues.

**Eureka! It worked 🎉**
Big props to the chatbots who helped clue me in - ChatGPT, Poe and especially Bard who provided the final hint. What a rollercoaster ride but so satisfying to crack it myself! 🙌

I hope this helps you and feel free to say hi on [Twitter](https://twitter.com/GodsloveADY)! Now back to building Modatongue.