How would one go about sorting ActiveStorage has_many_attached objects?
Hey there,
Just wondering if anyone can shed some light here as the Google search is pretty thin right now for ActiveStorage.
Is there a way to a a property (say sort_order) to each of the has_many_attached objects and then later be able to re-sort those without having to wrap the ActiveStorage items beneath a has_many associated model, e.g Image which itself has_attached a single attachment.
A working example is a classified advertisement that has many images, currently we have a has_many association to Image, but wanting to simply the creation process to take advantage of a multi-select option on the form upload.
Cheers
Aaron
Just wondering if anyone can shed some light here as the Google search is pretty thin right now for ActiveStorage.
Is there a way to a a property (say sort_order) to each of the has_many_attached objects and then later be able to re-sort those without having to wrap the ActiveStorage items beneath a has_many associated model, e.g Image which itself has_attached a single attachment.
A working example is a classified advertisement that has many images, currently we have a has_many association to Image, but wanting to simply the creation process to take advantage of a multi-select option on the form upload.
Cheers
Aaron
Hey Aaron,
At a high level:
You'd need something to sort by. You could modify the ActiveStorage models and add a column to sort by.
Or you could just keep an array of the attachment IDs for those on your model.
Either way would work, but I would probably prefer the second option. Once you have the attribute to sort by, you just grab the attachments order by the sort order that's saved.
At a high level:
You'd need something to sort by. You could modify the ActiveStorage models and add a column to sort by.
Or you could just keep an array of the attachment IDs for those on your model.
Either way would work, but I would probably prefer the second option. Once you have the attribute to sort by, you just grab the attachments order by the sort order that's saved.
Hey Chris,
Thanks for the answer, yes, at a high level that seems like a reasonable way to go about it, I think the flexibility of calling model.images scoped by the relevant order probably beats that at this time though so probably not worth the pain to migrate completely just for a simple bit of form magic!
I had always imagined ActiveStorage would end up with some kind of generator similar to ActiveRecord to allow this kind of extra rails goodness to be applied like adding your own properties to the attachments, scope the has_many_attacheds and so on.
Cheers
Aaron
Thanks for the answer, yes, at a high level that seems like a reasonable way to go about it, I think the flexibility of calling model.images scoped by the relevant order probably beats that at this time though so probably not worth the pain to migrate completely just for a simple bit of form magic!
I had always imagined ActiveStorage would end up with some kind of generator similar to ActiveRecord to allow this kind of extra rails goodness to be applied like adding your own properties to the attachments, scope the has_many_attacheds and so on.
Cheers
Aaron
Since the models are shared with ALL uploads, if you extend say ActiveStorage::Attachment, all attachments will have that functionality even though they might not need it.
ActiveStorage is quite a different approach than the other file uploading tools like Shrine. Plus it's fairly early right now and some of the functionality only works well with images (namely the variants stuff) which gets annoying if you want to do things like extend AS to make for transcoding video easier or whatever.
ActiveStorage is quite a different approach than the other file uploading tools like Shrine. Plus it's fairly early right now and some of the functionality only works well with images (namely the variants stuff) which gets annoying if you want to do things like extend AS to make for transcoding video easier or whatever.
Hi, @chris I am having this problem now trying to decide if to use ActiveStorage. If I go with your second option (I will have attachments in various places, and I think I will need sorting only in one case), what's the easiest/most efficient way of sorting the images by the given array of ids? Thanks!
In case others need this, I found this gem, it can sort by array of ids with a native SQL query and return a relation.
Add an Array/JSON Array type column to the model which declares the has_many_attached and store ids of ActiveStorage::Attachments in it. Then you can do :
# app/models/entry.rb
class Entry < ApplicationRecord
has_many_attached :pictures
def ordered_pictures
pictures.sort_by{ |pic| ordered_picture_ids.index(pic.id) || (pic.id*100) }
end
def ordered_picture_ids=(ids)
super(ids.map(&:to_i)) # convert any ids passed to this method to integer
# this is just for security reasons,
# you don't need to do this for the feature to work
end
end
more detailed example at: blog.eq8.eu/article/order-attachments-in-rails-activestorage-has_many_attached.html