Rails 和 Active Storage,如何直接在创建调用上分配附件?
Rails and Active Storage, how to assign attachment directly on the create call?
我 MyModel
有:
has_one_attached :video
我知道我能做到:
my_model = MyModel.create!()
my_model.video.attach(io: File.open("path/my_video.webm"), filename: "video.webm")
它工作正常。
但我想知道是否有一种方法可以将附件分配到 create()
调用中,例如:
MyModel.create!(
video: File.read("path/my_video.webm")
)
如果我执行上述操作,我会看到此错误:
/.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)
我试过这个:
MyModel.create!(
video: File.open("path/my_video.webm")
)
我收到这个错误:
/.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)
您可以通过创建 ActionDispatch::Http::UploadedFile
的实例来实现。这基本上只是一个临时文件实例的包装器,Rails 在处理文件上传时在内部使用它。
MyModel.create!(
video: ActionDispatch::Http::UploadedFile.new(
tempfile: File.open("path/my_video.webm"),
filename: "video.webm",
content_type: 'video/webm'
)
)
就效率或LOC而言,它实际上并没有比调用.attach
有任何优势。尽管在 JSON.
中处理作为 base64 编码字符串传递的文件是一个绝妙的技巧
此的“真实”用例:使用 factories 创建记录,在创建时验证附件的存在。
您可以为此使用 Rack::Test::UploadedFile
:
FactoryBot.define do
factory :my_model do
video { Rack::Test::UploadedFile.new(Rails.root.join("path", "my_video.webm"), "video/webm") }
end
end
我 MyModel
有:
has_one_attached :video
我知道我能做到:
my_model = MyModel.create!()
my_model.video.attach(io: File.open("path/my_video.webm"), filename: "video.webm")
它工作正常。
但我想知道是否有一种方法可以将附件分配到 create()
调用中,例如:
MyModel.create!(
video: File.read("path/my_video.webm")
)
如果我执行上述操作,我会看到此错误:
/.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)
我试过这个:
MyModel.create!(
video: File.open("path/my_video.webm")
)
我收到这个错误:
/.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)
您可以通过创建 ActionDispatch::Http::UploadedFile
的实例来实现。这基本上只是一个临时文件实例的包装器,Rails 在处理文件上传时在内部使用它。
MyModel.create!(
video: ActionDispatch::Http::UploadedFile.new(
tempfile: File.open("path/my_video.webm"),
filename: "video.webm",
content_type: 'video/webm'
)
)
就效率或LOC而言,它实际上并没有比调用.attach
有任何优势。尽管在 JSON.
此的“真实”用例:使用 factories 创建记录,在创建时验证附件的存在。
您可以为此使用 Rack::Test::UploadedFile
:
FactoryBot.define do
factory :my_model do
video { Rack::Test::UploadedFile.new(Rails.root.join("path", "my_video.webm"), "video/webm") }
end
end