Search code examples
ruby-on-railsrails-activestorageruby-on-rails-5.2

How do you solve N+1 for ActiveStorage URLs?


How do you preload all the records with their URLs?

This is what I am doing in my jbuilder to get the URLs:

# views/users/index.json.jbuilder
...
json.avatar_url user.avatar.attached? && rails_blob_url(user.avatar)
...


Comment
    has_one :user

User
    has_one_attached :avatar

How would you preload all the users and their avatars?


Comments.includes(users: :avatar)

yields the following error:

ActiveRecord::AssociationNotFoundError (Association named 'avatar' was not found on User; perhaps you misspelled it?)

The same error pops up when executing:

User.includes(:avatar)

Solution

  • For a singular attachment named :avatar, Active Storage adds a with_attached_avatar scope that preloads the relevant associations:

    @users.with_attached_avatar.each do |user|
      # ...
    end
    

    See the API documentation for has_one_attached.