I have a model with attachments:
class Project < ApplicationRecord has_many_attached :images end
When I attach and save the image I also want to save an additional custom attribute - display_order
(integer) with the attached image. I want to use it to sort the attached images and display them in the order I specified in this custom attribute. I've reviewed ActiveStorage source code for #attach
method as well as ActiveStorage::Blob
model but it looks like there is no built in method to pass some custom metadata.
I wonder, what's the idiomatic way to solve this problem with ActiveStorage? In the past I would usually just add a display_order
attribute to the ActiveRecord model which represents my attachment and then simply use it with .order(display_order: :asc)
query.
If you need to store additional data with each image and perform queries based on that data, I’d recommend extracting an Image
model that wraps an attached file
:
# app/models/project.rb class Project < ApplicationRecord has_many :images, dependent: :destroy end
# app/models/image.rb class Image < ApplicationRecord belongs_to :project has_one_attached :file delegate_missing_to :file scope :positioned, -> { order(position: :asc) } end
<%# app/views/projects/show.html.erb %> <% @project.images.positioned.each do |image| %> <%= image_tag image %> <% end %>
Note that the example view above causes 2N+1 queries for a project with N images (one query for the project’s images, another for each image’s ActiveStorage::Attachment
record, and one more for each attached ActiveStorage::Blob
). I deliberately avoided optimizing the number of queries for clarity’s sake.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With