Is there any supported way to store the id of the attacher as an attribute, as we can store metadata attributes with the metadata_attributes plugin? Using shrine with activerecord.
I need to detect then the “id” change (when a file attached is change) and is already uploaded to store to trigger some actions through subscribers.
It seems the metadata_attributes changes are triggered on any method that calls Attacher#write, is that the right place to look at?
Is this something useful as a plugin/PR or you think is a very special requirement?
Yeah, I don’t know how many people will need this functionality, so I’m not sure whether it belongs in the core. For your use case, could you use #<name>_changed?? It returns true when a new file is attached, otherwise it returns false, including when the cached file was promoted to permanent storage (and I don’t know whether you need to detect that as well):
The metadata attributes plugin doesn’t seem the right place to add it as it’s intended for the metadata hash.
Yeah, it would be convenient if we had a file_attributes plugin that would include the metadata_attributes behaviour, but also allow you to forward id and storage. There is probably benefit in being able to have this data written in individual columns (like what Active Storage has), I’m just looking for a strong enough use case.
That was my first try, but on my use case #<name>_changed? is always returning false and that was the reason i was looking to have the id store (as i can’t check #<name>_data_changed? because it changed both in upload/caching and on promotion).
I’m not sure why is always returning false, maybe is because i’m using shrine with multiple uploads as explained here (object with nested shrine uploads with activerecord) and the save is done through the parent object, not the upload itself.
To be more specific, I have a gallery object with multiple image objects, so i save the gallery and all the images are automatically saved, but all the images that are created/updated return false for the image_changed? call.
This ugly hack on the image object works though
image_id_changed = false
if self.previous_changes['image_data'] && self.image.storage_key == :store #in store
if self.previous_changes['image_data'] #updated value
previous = JSON.parse(self.previous_changes['image_data'])
current = JSON.parse(self.previous_changes['image_data'])
image_id_changed = (previous['id'] != current['id'])
image_id_changed = true #new value
So having the id stored as a single column will make things easier. But i know that could be a very specific requests so i can live with a custom hack
Thanks for explaining. It’s strange that #<name>_changed? always returns false for you, the default multiple files setup should trigger dirty checking for nested resources, because it should still call model.attachment = in the end.
FWIW, the Attacher#column_values patch I proposed should work, as Attacher#column_values is public API.