Search code examples
ruby-on-railsrubyruby-on-rails-6rails-activestorage

Rails ActiveStorage scope for when file is NOT attached


When using ActiveStorage, how do you create a scope for when files are NOT attached.

For example:

class Check < ActiveRecord::Base
  has_one_attached :image
end

I want something like Check.has_no_attached_image to return only records where there is no existing attached image.

Found an answer for the case where image are attached but not the opposite
scope :has_attached_image, -> { joins(image_attachment: :blob) }


Solution

  • You can do that using left_joins with the name of the association (image + _attachment) which is interpreted as:

    SELECT users.*
    FROM users LEFT OUTER JOIN active_storage_attachments
    ON active_storage_attachments.record_id = users.id
    AND active_storage_attachments.record_type = 'User'
    AND active_storage_attachments.name = 'image'
    

    And then apply a WHERE filter to get those user rows without match against the active_storage_attachments table:

    User.left_joins(:image_attachment).where(active_storage_attachments: { id: nil })