Search code examples
ruby-on-railsrails-activestorage

List ActiveStorage attachments indirectly related to model


I am new to Rails and am trying to understand how ActiveStorage works.

The app has the following models:

class Client < ApplicationRecord
    has_many :jobs
    has_many :messages
end
class Job < ApplicationRecord
    belongs_to :client
    has_many_attached :images
end
class Message < ApplicationRecord
    belongs_to :client
    has_many_attached :images
end

In the database I can see the polymorphic relationship and I can also understand what SQL query would get me the desired results.

However I was wondering if there is an idiomatic and efficient way to retrieve all the attachments related to a client?


Solution

  • Querying attachments associated with a given record

    You can query for attachments directly using the ActiveStorage::Attachment class. The record attribute is the polymorphic association which joins to the attached class.

    Here’s an example

    ActiveStorage::Attachment.where(record: Job.first)
    

    Querying attachments associated with a set of records

    You can also pass a set of records to the record option

    ActiveStorage::Attachment.where(record: Job.all)
    

    Querying attachments associated with multiple sets of records

    You can find attachments associated with multiple sets of records using or

    ActiveStorage::Attachment.where(record: Job.all).or(ActiveStorage::Attachment.where(record: Message.all))
    

    Putting it together...

    To find all the attachments associated with multiple sets of records associated with a given record

    client = Client.first
    ActiveStorage::Attachment.where(record: client.jobs).or(ActiveStorage::Attachment.where(record: client.messages))
    

    It’s not pretty, but it’s efficient. All the querying is done via Active Record which means it happens in a single SQL statement and doesn’t require loading any objects into memory.