Aug 02, 2022

Finding Active record objects without any Active storage attachments in Rails

This is more of a note to myself as I find myself googling this quite often. Let's say you have a model named Project which has one Active storage attachment called avatar per each record:

class Project < ApplicationRecord
  has_one_attached :avatar
end

To find projects which do not have any attached avatars we use the :missing query introduced in Rails 6.1

Project.where.missing(:avatar_attachment)

If you are not using Rails 6.1 or later version of Rails you can use left_joins

Project.left_joins(:avatar_attachment).where(avatar_attachment: {id: nil})

In case you have multiple attachments per record like this:

class Project < ApplicationRecord
  has_many_attached :images
end

The queries look a little bit different

For Rails 6.1+

Project.where.missing(:images_attachments)

Below Rails 6.1

Project.left_joins(:images_attachments).where(images_attachments: {id: nil})

Active storage attachments have a little bit different table names as compared to other associations as they share the same table. You can always find out how Rails is referring to your active storage attachments using this query

Model._reflections.keys

This works for regular associations as well. Let's say

class Author < ApplicationRecord
  has_many :books
end

Finding an author without any books.

Author.where.missing(:books)
# or
Author.left_joins(:books).where(books: {id: nil})

Subscribe to Open Source Businees Newsletter

Twice a month we will interview people behind open source businesses. We will talk about how they are building a business on top of open source projects.

We'll never share your email with anyone else.