bullet-train-co / bullet_train

The Open Source Ruby on Rails SaaS Template
MIT License
1.58k stars 245 forks source link

Images added to a `trix_editor` field go missing after save #1580

Open jagthedrummer opened 3 days ago

jagthedrummer commented 3 days ago

I have a CLOUDINARY_URL ENV var set, so images should be handled by Cloudinary.

I'm trying to add an image to a trix_editor field.

CleanShot 2024-07-03 at 12 54 34

After saving the record, the image is not shown as being in the description field on the detail page.

CleanShot 2024-07-03 at 12 59 59

If I inspect the area where the image should be there seems to be no trace of it at all.

CleanShot 2024-07-03 at 13 03 54

And when I edit the record again it does not appear in the editor.

CleanShot 2024-07-03 at 13 00 13

When I first add the image to the trix_editor field I do see some activity in the server console. It looks like it's trying to use ActiveStorage instead of Cloudinary. But even so, the image seems to disappear.

web              | Started POST "/rails/active_storage/direct_uploads" for 127.0.0.1 at 2024-07-03 12:56:26 -0500
web              | Processing by ActiveStorage::DirectUploadsController#create as JSON
web              |   Parameters: {"blob"=>{"filename"=>"octologo.png", "content_type"=>"image/png", "byte_size"=>37704, "checksum"=>"Ie/PDMVxedyfh3uThe6XLg=="}, "direct_upload"=>{"blob"=>{"filename"=>"octologo.png", "content_type"=>"image/png", "byte_size"=>37704, "checksum"=>"Ie/PDMVxedyfh3uThe6XLg=="}}}
web              |   TRANSACTION (1.6ms)  BEGIN
web              |   ActiveStorage::Blob Create (5.9ms)  INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at", "service_name") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["key", "xifka3lkyt4p9lv28b5zspbi2ei6"], ["filename", "octologo.png"], ["content_type", "image/png"], ["metadata", nil], ["byte_size", 37704], ["checksum", "Ie/PDMVxedyfh3uThe6XLg=="], ["created_at", "2024-07-03 17:56:26.158056"], ["service_name", "local"]]
web              |   TRANSACTION (1.2ms)  COMMIT
web              |   Disk Storage (0.1ms) Generated URL for file at key: xifka3lkyt4p9lv28b5zspbi2ei6 (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDam9JYTJWNVNTSWhlR2xtYTJFemJHdDVkRFJ3T1d4Mk1qaGlOWHB6Y0dKcE1tVnBOZ1k2QmtWR09oRmpiMjUwWlc1MFgzUjVjR1ZKSWc1cGJXRm5aUzl3Ym1jR093WlVPaE5qYjI1MFpXNTBYMnhsYm1kMGFHa0NTSk02RFdOb1pXTnJjM1Z0U1NJZFNXVXZVRVJOVm5obFpIbG1hRE4xVkdobE5saE1aejA5QmpzR1ZEb1JjMlZ5ZG1salpWOXVZVzFsT2dwc2IyTmhiQT09IiwiZXhwIjoiMjAyNC0wNy0wM1QxODowMToyNi4xNjdaIiwicHVyIjoiYmxvYl90b2tlbiJ9fQ==--d41bbb973a51fab899c032d4148630d228995b06)
web              | Completed 200 OK in 11ms (Views: 0.1ms | ActiveRecord: 7.2ms | Allocations: 4582)
web              |
web              |
web              | Started PUT "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDam9JYTJWNVNTSWhlR2xtYTJFemJHdDVkRFJ3T1d4Mk1qaGlOWHB6Y0dKcE1tVnBOZ1k2QmtWR09oRmpiMjUwWlc1MFgzUjVjR1ZKSWc1cGJXRm5aUzl3Ym1jR093WlVPaE5qYjI1MFpXNTBYMnhsYm1kMGFHa0NTSk02RFdOb1pXTnJjM1Z0U1NJZFNXVXZVRVJOVm5obFpIbG1hRE4xVkdobE5saE1aejA5QmpzR1ZEb1JjMlZ5ZG1salpWOXVZVzFsT2dwc2IyTmhiQT09IiwiZXhwIjoiMjAyNC0wNy0wM1QxODowMToyNi4xNjdaIiwicHVyIjoiYmxvYl90b2tlbiJ9fQ==--d41bbb973a51fab899c032d4148630d228995b06" for 127.0.0.1 at 2024-07-03 12:56:26 -0500
web              | Processing by ActiveStorage::DiskController#update as */*
web              |   Parameters: {"encoded_token"=>"[FILTERED]"}
web              |   Disk Storage (0.6ms) Uploaded file to key: xifka3lkyt4p9lv28b5zspbi2ei6 (checksum: Ie/PDMVxedyfh3uThe6XLg==)
web              | Completed 204 No Content in 1ms (ActiveRecord: 0.0ms | Allocations: 635)
web              |
web              |
web              | Started GET "/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c7947d84eadfe128bf7bcd5b83245ad4d45e6491/octologo.png" for 127.0.0.1 at 2024-07-03 12:56:26 -0500
web              | Processing by ActiveStorage::Blobs::RedirectController#show as PNG
web              |   Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c7947d84eadfe128bf7bcd5b83245ad4d45e6491", "filename"=>"octologo"}
web              |   ActiveStorage::Blob Load (0.9ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 5], ["LIMIT", 1]]
web              |   Disk Storage (9.3ms) Generated URL for file at key: xifka3lkyt4p9lv28b5zspbi2ei6 (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhlR2xtYTJFemJHdDVkRFJ3T1d4Mk1qaGlOWHB6Y0dKcE1tVnBOZ1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUTJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05amRHOXNiMmR2TG5CdVp5STdJR1pwYkdWdVlXMWxLajFWVkVZdE9DY25iMk4wYjJ4dloyOHVjRzVuQmpzR1ZEb1JZMjl1ZEdWdWRGOTBlWEJsU1NJT2FXMWhaMlV2Y0c1bkJqc0dWRG9SYzJWeWRtbGpaVjl1WVcxbE9ncHNiMk5oYkE9PSIsImV4cCI6IjIwMjQtMDctMDNUMTg6MDE6MjYuMjc3WiIsInB1ciI6ImJsb2Jfa2V5In19--7347e41065578d13c6e63c16900927f9f109e409/octologo.png)
web              | Redirected to http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhlR2xtYTJFemJHdDVkRFJ3T1d4Mk1qaGlOWHB6Y0dKcE1tVnBOZ1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUTJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05amRHOXNiMmR2TG5CdVp5STdJR1pwYkdWdVlXMWxLajFWVkVZdE9DY25iMk4wYjJ4dloyOHVjRzVuQmpzR1ZEb1JZMjl1ZEdWdWRGOTBlWEJsU1NJT2FXMWhaMlV2Y0c1bkJqc0dWRG9SYzJWeWRtbGpaVjl1WVcxbE9ncHNiMk5oYkE9PSIsImV4cCI6IjIwMjQtMDctMDNUMTg6MDE6MjYuMjc3WiIsInB1ciI6ImJsb2Jfa2V5In19--7347e41065578d13c6e63c16900927f9f109e409/octologo.png
web              | Completed 302 Found in 40ms (ActiveRecord: 16.9ms | Allocations: 25774)
web              |
web              |
web              | Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhlR2xtYTJFemJHdDVkRFJ3T1d4Mk1qaGlOWHB6Y0dKcE1tVnBOZ1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUTJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW05amRHOXNiMmR2TG5CdVp5STdJR1pwYkdWdVlXMWxLajFWVkVZdE9DY25iMk4wYjJ4dloyOHVjRzVuQmpzR1ZEb1JZMjl1ZEdWdWRGOTBlWEJsU1NJT2FXMWhaMlV2Y0c1bkJqc0dWRG9SYzJWeWRtbGpaVjl1WVcxbE9ncHNiMk5oYkE9PSIsImV4cCI6IjIwMjQtMDctMDNUMTg6MDE6MjYuMjc3WiIsInB1ciI6ImJsb2Jfa2V5In19--7347e41065578d13c6e63c16900927f9f109e409/octologo.png" for 127.0.0.1 at 2024-07-03 12:56:26 -0500
web              | Processing by ActiveStorage::DiskController#show as PNG
web              |   Parameters: {"encoded_key"=>"[FILTERED]", "filename"=>"octologo"}
web              | Completed 200 OK in 0ms (ActiveRecord: 0.0ms | Allocations: 259)
web              |
web              |

In a console I can see that an ActiveStorage::Blob record was created for the file:

> ActiveStorage::Blob.last
D, [2024-07-03T13:08:41.715056 #18698] DEBUG -- :   ActiveStorage::Blob Load (0.4ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" ORDER BY "active_storage_blobs"."id" DESC LIMIT $1  [["LIMIT", 1]]
=>
#<ActiveStorage::Blob:0x000000012f993c18
 id: 5,
 key: "xifka3lkyt4p9lv28b5zspbi2ei6",
 filename: "octologo.png",
 content_type: "image/png",
 metadata: {"identified"=>true, "width"=>200, "height"=>200, "analyzed"=>true},
 byte_size: 37704,
 checksum: "Ie/PDMVxedyfh3uThe6XLg==",
 created_at: Wed, 03 Jul 2024 17:56:26.158056000 UTC +00:00,
 service_name: "local">

And I can see that a new file exists in the storage/ directory matching the key of the blob that was created.

$ ls -al storage/xi/fk/xifka3lkyt4p9lv28b5zspbi2ei6
-rw-r--r--  1 jgreen  staff    37K Jul  3 12:56 storage/xi/fk/xifka3lkyt4p9lv28b5zspbi2ei6

I've also tried this same test without having the CLOUDINARY_URL ENV var in place and I still get the same result.

jagthedrummer commented 3 days ago

I think this line is responsible for stripping the attachment info:

https://github.com/bullet-train-co/bullet_train-core/blob/4aacb3036a944708d03583a700efdccd302760ab/bullet_train-fields/app/helpers/fields/html_editor_helper.rb#L8

jagthedrummer commented 3 days ago

Here's a test that I ran to isolate that line:

rt = ActionText::RichText.find 6

irb(main):049> string = rt.body.to_trix_html
D, [2024-07-03T13:39:58.315078 #18698] 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]]
=> "<div>This is a task with an image.<br><br>Here's the image:<br><br><figure data-trix-attachment=\"{&quot;sgid&quot;:&quot;eyJfcmFpbHMiOnsibWVzc2FnZS...
irb(main):050> string
=> "<div>This is a task with an image.<br><br>Here's the image:<br><br><figure data-trix-attachment=\"{&quot;sgid&quot;:&quot;eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJalJuYVdRNkx5OW5ZVzFsTFdSaGVTOUJZM1JwZG1WVGRHOXlZV2RsT2pwQ2JHOWlMelVfWlhod2FYSmxjMTlwYmdZNkJrVlUiLCJleHAiOm51bGwsInB1ciI6ImF0dGFjaGFibGUifX0=--eaa74e1d5dc9c336f243a08ff9b56a1f7a55984a&quot;,&quot;contentType&quot;:&quot;image/png&quot;,&quot;url&quot;:&quot;http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c7947d84eadfe128bf7bcd5b83245ad4d45e6491/octologo.png&quot;,&quot;filename&quot;:&quot;octologo.png&quot;,&quot;filesize&quot;:37704,&quot;width&quot;:200,&quot;height&quot;:200,&quot;previewable&quot;:true,&quot;content&quot;:&quot;&quot;}\" data-trix-attributes=\"{&quot;presentation&quot;:&quot;gallery&quot;}\"></figure><br><br>Here's some text after the image</div>"

irb(main):052> string = string.gsub("bullettrain://", TEMPORARY_REPLACEMENT)
=> "<div>This is a task with an image.<br><br>Here's the image:<br><br><figure data-trix-attachment=\"{&quot;sgid&quot;:&quot;eyJfcmFpbHMiOnsibWVzc2FnZS...
irb(main):053> string
=> "<div>This is a task with an image.<br><br>Here's the image:<br><br><figure data-trix-attachment=\"{&quot;sgid&quot;:&quot;eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJalJuYVdRNkx5OW5ZVzFsTFdSaGVTOUJZM1JwZG1WVGRHOXlZV2RsT2pwQ2JHOWlMelVfWlhod2FYSmxjMTlwYmdZNkJrVlUiLCJleHAiOm51bGwsInB1ciI6ImF0dGFjaGFibGUifX0=--eaa74e1d5dc9c336f243a08ff9b56a1f7a55984a&quot;,&quot;contentType&quot;:&quot;image/png&quot;,&quot;url&quot;:&quot;http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c7947d84eadfe128bf7bcd5b83245ad4d45e6491/octologo.png&quot;,&quot;filename&quot;:&quot;octologo.png&quot;,&quot;filesize&quot;:37704,&quot;width&quot;:200,&quot;height&quot;:200,&quot;previewable&quot;:true,&quot;content&quot;:&quot;&quot;}\" data-trix-attributes=\"{&quot;presentation&quot;:&quot;gallery&quot;}\"></figure><br><br>Here's some text after the image</div>"

irb(main):054> string = sanitize(string, tags: %w[div br strong em b i del a h1 blockquote pre ul ol li], attributes: %w[href])
=> "<div>This is a task with an image.<br><br>Here's the image:<br><br><br><br>Here's some text after the image</div>"
irb(main):055> string
=> "<div>This is a task with an image.<br><br>Here's the image:<br><br><br><br>Here's some text after the image</div>"