Here's a fun ActiveStorage issue which has been causing me to scratch my head in confusion for a couple of days; ActiveStorage seems to not be playing well with either fixture_file_upload
& Rack::Test::UploadedFile
as both methods are throwing the following error when saving a file to a model attachment using ActiveStorage:
Loading development environment (Rails 6.0.3.4)
irb(main):001:0> Attachment.create({file: Rack::Test::UploadedFile.new("#{Rails.root}/test/fixtures/files/tracer1.jpg", 'tracer1.jpg')})
D, [2021-01-22T16:20:03.695894 #498] DEBUG -- : (0.3ms) BEGIN
D, [2021-01-22T16:20:03.730325 #498] DEBUG -- : Attachment Create (0.8ms) INSERT INTO "attachments" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2021-01-22 16:20:03.726078"], ["updated_at", "2021-01-22 16:20:03.726078"]]
D, [2021-01-22T16:20:03.735233 #498] DEBUG -- : ActiveStorage::Attachment Load (0.4ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 1], ["record_type", "Attachment"], ["name", "file"], ["LIMIT", 1]]
D, [2021-01-22T16:20:03.736695 #498] DEBUG -- : ActiveStorage::Blob Create (0.3ms) INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["key", "uk44hg6aeqgkijnoti7625kmymn5"], ["filename", "tracer1.jpg"], ["content_type", "image/jpeg"], ["metadata", "{"identified":true}"], ["byte_size", 71843], ["checksum", "fleS+FPvNcLEHaUysUgaGQ=="], ["created_at", "2021-01-22 16:20:03.735850"]]
D, [2021-01-22T16:20:03.737593 #498] DEBUG -- : ActiveStorage::Attachment Create (0.4ms) INSERT INTO "active_storage_attachments" ("name", "record_type", "record_id", "blob_id", "created_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["name", "file"], ["record_type", "Attachment"], ["record_id", 1], ["blob_id", 4], ["created_at", "2021-01-22 16:20:03.736870"]]
D, [2021-01-22T16:20:03.739022 #498] DEBUG -- : Attachment Update (0.3ms) UPDATE "attachments" SET "updated_at" = $1 WHERE "attachments"."id" = $2 [["updated_at", "2021-01-22 16:20:03.737884"], ["id", 1]]
D, [2021-01-22T16:20:03.740233 #498] DEBUG -- : (1.1ms) COMMIT
I, [2021-01-22T16:20:03.740753 #498] INFO -- : Disk Storage (0.0ms) Deleted file from key: uk44hg6aeqgkijnoti7625kmymn5
I, [2021-01-22T16:20:03.740868 #498] INFO -- : Disk Storage (0.5ms) Uploaded file to key: uk44hg6aeqgkijnoti7625kmymn5 (checksum: fleS+FPvNcLEHaUysUgaGQ==)
Traceback (most recent call last):
1: from (irb):1
ActiveStorage::IntegrityError (ActiveStorage::IntegrityError)
This issue, however, isn't seen when using the following method of attaching a file.
irb(main):001:0> attachment = Attachment.new
=> #<Attachment id: nil, created_at: nil, updated_at: nil, parent_type: nil, parent_id: nil, frame: "{}", user_id: nil>
irb(main):002:0> attachment.file.attach(io: File.open(Rails.root + 'test/fixtures/files/tracer1.jpg'), filename: 'tracer1.jpg', content_type: 'image/jpg')
=> #<ActiveStorage::Attached::Changes::CreateOne:0x0000563b16d6bdc8 @name="file", @record=#<Attachment id: nil, created_at: nil, updated_at: nil, parent_type: nil, parent_id: nil, frame: "{}", user_id: nil>, @attachable={:io=>#<File:/app/test/fixtures/files/tracer1.jpg>, :filename=>"tracer1.jpg", :content_type=>"image/jpg"}>
irb(main):003:0> attachment.save
D, [2021-01-22T16:21:55.564371 #516] DEBUG -- : (0.2ms) BEGIN
D, [2021-01-22T16:21:55.610210 #516] DEBUG -- : Attachment Create (0.5ms) INSERT INTO "attachments" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2021-01-22 16:21:55.605710"], ["updated_at", "2021-01-22 16:21:55.605710"]]
D, [2021-01-22T16:21:55.615088 #516] DEBUG -- : ActiveStorage::Attachment Load (0.4ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["record_id", 2], ["record_type", "Attachment"], ["name", "file"], ["LIMIT", 1]]
D, [2021-01-22T16:21:55.617341 #516] DEBUG -- : ActiveStorage::Blob Create (0.6ms) INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["key", "hjmhqkujbe2uxk6f9jfgmq5j4nn7"], ["filename", "tracer1.jpg"], ["content_type", "image/jpeg"], ["metadata", "{"identified":true}"], ["byte_size", 71843], ["checksum", "fleS+FPvNcLEHaUysUgaGQ=="], ["created_at", "2021-01-22 16:21:55.615787"]]
D, [2021-01-22T16:21:55.618972 #516] DEBUG -- : ActiveStorage::Attachment Create (0.7ms) INSERT INTO "active_storage_attachments" ("name", "record_type", "record_id", "blob_id", "created_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["name", "file"], ["record_type", "Attachment"], ["record_id", 2], ["blob_id", 5], ["created_at", "2021-01-22 16:21:55.617781"]]
D, [2021-01-22T16:21:55.621752 #516] DEBUG -- : Attachment Update (0.5ms) UPDATE "attachments" SET "updated_at" = $1 WHERE "attachments"."id" = $2 [["updated_at", "2021-01-22 16:21:55.619356"], ["id", 2]]
D, [2021-01-22T16:21:55.627906 #516] DEBUG -- : (6.0ms) COMMIT
I, [2021-01-22T16:21:55.628651 #516] INFO -- : Disk Storage (0.4ms) Uploaded file to key: hjmhqkujbe2uxk6f9jfgmq5j4nn7 (checksum: fleS+FPvNcLEHaUysUgaGQ==)
I, [2021-01-22T16:21:55.632122 #516] INFO -- : Enqueued ActiveStorage::AnalyzeJob (Job ID: 5e869e72-e190-4a73-8938-14db177822a0) to Async(active_storage_analysis) with arguments: #<GlobalID:0x0000563b18c40938 @uri=#<URI::GID gid://cosplay/ActiveStorage::Blob/5>>
=> true
irb(main):004:0> D, [2021-01-22T16:21:55.691199 #516] DEBUG -- : ActiveStorage::Blob Load (0.3ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", 5], ["LIMIT", 1]]
I, [2021-01-22T16:21:55.691873 #516] INFO -- : Performing ActiveStorage::AnalyzeJob (Job ID: 5e869e72-e190-4a73-8938-14db177822a0) from Async(active_storage_analysis) enqueued at 2021-01-22T16:21:55Z with arguments: #<GlobalID:0x0000563b1947abf8 @uri=#<URI::GID gid://cosplay/ActiveStorage::Blob/5>>
I, [2021-01-22T16:21:55.797208 #516] INFO -- : Disk Storage (0.1ms) Downloaded file from key: hjmhqkujbe2uxk6f9jfgmq5j4nn7
D, [2021-01-22T16:21:55.845133 #516] DEBUG -- : (0.4ms) BEGIN
D, [2021-01-22T16:21:55.845853 #516] DEBUG -- : ActiveStorage::Blob Update (0.5ms) UPDATE "active_storage_blobs" SET "metadata" = $1 WHERE "active_storage_blobs"."id" = $2 [["metadata", "{"identified":true,"width":575,"height":862,"analyzed":true}"], ["id", 5]]
D, [2021-01-22T16:21:55.847209 #516] DEBUG -- : (0.9ms) COMMIT
I, [2021-01-22T16:21:55.847513 #516] INFO -- : Performed ActiveStorage::AnalyzeJob (Job ID: 5e869e72-e190-4a73-8938-14db177822a0) from Async(active_storage_analysis) in 155.55ms
Here's the model used in the above 2 examples.
class Attachment < ApplicationRecord
has_one_attached :file, dependent: :destroy
end
I really appreciate any help or insight anyone out there has on this issue; I essentially have a very large test suite which uses fixture_file_upload
& Rack::Test::UploadedFile
pretty much everywhere as they are very useful, however, as you can see they are not working anymore in combination with ActiveStorage.
Here are my Gemfile & Gemfile.lock if it helps debug what's going on; I've also included a minitest test file on that gist which has 2 failing and 1 succeeding test. I am happy to provide any additional details if it helps debug the issue.
Additional details which could be helpful:
Docker version 20.10.2, build 2291f61
docker-compose version 1.25.5, build unknown
question from:
https://stackoverflow.com/questions/65849252/fixture-file-upload-racktestuploadedfile-activestorageintegrityerror