Search code examples
ruby-on-railsruby-on-rails-5rails-activestorage

Rails 5 Active Storage: Is there a more efficient way of displaying multiple image attachments?


I have a model named Job. It has one Active Storage attachment.

class Job < ApplicationRecord
  # ...
  has_one_attached :image
end

I will eventually paginate the results but at the moment, JobsController#index returns all jobs:

class JobsController < ApplicationController
  def index
    @jobs = Job.all
  end
end

Since all 2000 seeded rows are displayed on the index page, I can see that loaded all images takes a long time.

<% @jobs.each do |job| %>
<div class="listing">
  <div class="image">
    <%= image_tag url_for(job.image) %>
  </div>
  ...
</div>

Eventually, I only intend to display 50 or so at a time but this has led me to wondering if there isn't a more efficient way of loading multiple images.

What steps do I need to take to ensure that images are delivered quickly and with minimal strain on the app? Am I doing it in the most efficient way?


Solution

  • Rails has a method for retrieving associations all at once. It's called "eager loading" and in your case it would look like this:

    @jobs = Job.with_attached_image.all
    

    This grabs all @jobs with images attached already. This is a special case because it's using the Rails has_one_attached model attribute. Normally, we handle preloading nested associations like:

    @jobs.includes(:image)
    

    Source: Rails Eager Loading

    Eager loading will make your queries a lot simpler and faster.