We have been using rails 5.2RC1 for a couple weeks on a small number of production apps to test ActiveStorage. We've been able to get everything working with our Heroku instances (including PDF previews), but are now running into some questions around best practices.
Say we have the following model:
class Contract < ApplicationRecord
has_many_attached :documents
end
This works perfectly.
However now we want to add some additional data about each individual document. Perhaps things like the type of document for the contract or some other type of metadata.
Our first thought was to try and stuff this into the metadata attribute of the blob, but that doesn't feel right.
The other thought that we had was to change the design to something like this:
class Contract < ApplicationRecord
has_many :documents
end
class Document < ApplicationRecord
belongs_to :contract
has_many_attached :files
end
Then using the document model to keep information about each attached file. Say in this example a contract has an original document, but then in the future there could be addendum attached to it that have their own unique properties that we would want to keep track of.
Thoughts?
At the time this question was asked, it's probably the case that metadata was getting overwritten as described in this Github issue. While metadata still isn't queryable (come on guys, nearly 5 years has passed), you can definitely add custom attributes.
The weird thing is that the attach() function param metadata says in the docs it is supposed to be a string, but that doesn't work and gets overwritten by the analyzer. If you just change it to an object-literal instead, that works and the custom metadata gets merged with the analyzer metadata.
So this works:
payment.archives.attach(
io: File.open("./archive.zip"),
filename: "archive.zip",
content_type: "application/gzip",
metadata: { customTag: "some value" }
)
But passing the metadata as a stringified object does not:
payment.archives.attach(
io: File.open("./archive.zip"),
filename: "archive.zip",
content_type: "application/gzip",
metadata: "{ \"customTag\": \"some value\" }"
)
Also, you can pass an ActionDispatch::Http::UploadedFile object as a param to io: which the docs also aren't clear on.. In my use case (and I imagine many others) I had an UploadedFile object coming from a multipart form request and needed to add some custom attributes to each file. hopefully this helps someone who is lost in legacy rails hell another 5 years from now.
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