I have MyModel
with:
has_one_attached :video
I see I can do this:
my_model = MyModel.create!()
my_model.video.attach(io: File.open("path/my_video.webm"), filename: "video.webm")
And it works properly.
But I am wondering if there is a way of doing the attachment assignation into the create()
call like:
MyModel.create!(
video: File.read("path/my_video.webm")
)
If I do the above I see this error:
/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/activesupport-6.1.4.1/lib/active_support/message_verifier.rb:176:in `verify': ActiveSupport::MessageVerifier::InvalidSignature (ActiveSupport::MessageVerifier::InvalidSignature)
I've tried this:
MyModel.create!(
video: File.open("path/my_video.webm")
)
I am get this error:
/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/activestorage-6.1.4.1/lib/active_storage/attached/changes/create_one.rb:74:in `find_or_build_blob': Could not find or build blob: expected attachable, got #File:/Users/fernando.guillen/Development/PlaycocolaBackend/test/fixtures/files/video.webm (ArgumentError)
CodePudding user response:
You can do it by creating an instance of ActionDispatch::Http::UploadedFile
. This is basically just a wrapper around a tempfile instance which Rails uses internally when dealing with file uploads.
MyModel.create!(
video: ActionDispatch::Http::UploadedFile.new(
tempfile: File.open("path/my_video.webm"),
filename: "video.webm",
content_type: 'video/webm'
)
)
In terms of efficiency or LOC it doesn't really have any advantages over calling .attach
. It is a nifty trick though for dealing with files passed as base64 encoded strings in JSON.