Although the approach by roshiend was downvoted, I think that it would work fine for me, so I tried it out. The following code works, but only on creating new attachment blobs. It fails to work correctly when updating, although there are workarounds.
This seems to uncover a bug in AA for (in my case) nested polymorphic resources so I am reaching out to see if I am doing anything wrong before I file an issue with AA. Can anyone see if I went wrong somewhere?
Bug Summary
In nested forms, polymorphic image attachment does not upload a new file (when replacing an existing one), nor can it be displayed as an image hint, when using ActiveStorage as the file uploader.
Expected behavior
When editing a resource with an attached image blob, I expect (1) to be able to display a small thumbnail using "hint:" and I expect when choosing a new file that the old file is overwritten. I expect (2) the same behavior when this resource is nested into another resource, and the form with f.has_many is implemented.
Actual behavior
Expectation (1) works fine. But implementing (2) I find that the old file is not overwritten with the new file (returns Completed 304 Not Modified). Furthermore if I try to show a thumbnail in the sub-form using "hint:" I get an exception
Can't resolve image into URL: to_model delegated to attachment, but attachment is nil
The problem it seems is inside the has_many the .image method loses touch with the attachment object.
How to reproduce
Given a model and a polymorphic attachments model:
class PayloadKind < ApplicationRecord
has_many :attachments, as: :attachable
accepts_nested_attributes_for :attachments, allow_destroy: true
end
class Attachment < ApplicationRecord
belongs_to :attachable, polymorphic: true
has_one_attached :image
end
First, look at the form for Attachment:
ActiveAdmin.register Attachment do
permit_params :name, :image
form do |f|
f.inputs "attachment" do
f.input :name
f.input :image, as: :file, hint: image_tag(f.object.image.variant(resize_to_limit: [100,100])) # hint: works fine
end
f.actions # uploads a new file if the user wants a change
end
When I view the form, the image hint shows up fine. When I execute the update using the above form, with a new file specified to replace the old one, the log shows expected behavior
ActiveStorage::Blob Load (0.2ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2 [["id", 52], ["LIMIT", 1]]
Disk Storage (0.1ms) Checked if file exists at key: variants/vw057sxlchfi6omkig359sa893hs/6fc72cc8335bf38f78ee581ac0cfbf2ff591b7f70c9c06b30882cae6844770c8 (no)
Disk Storage (0.7ms) Downloaded file from key: vw057sxlchfi6omkig359sa893hs
Disk Storage (0.4ms) Uploaded file to key: variants/vw057sxlchfi6omkig359sa893hs/6fc72cc8335bf38f78ee581ac0cfbf2ff591b7f70c9c06b30882cae6844770c8
Now edit the same Attachment instance, but nested in the form for PayloadKind
ActiveAdmin.register PayloadKind do
permit_params :id, :name, :variety, :description, attachments_attributes: [:name, :image, :id, :attachable_id, :attachable_type, :_destroy]
form do |f|
f.semantic_errors
f.inputs "parameters" do
f.input :name
f.input :variety
f.input :description
f.object.attachments.each do |at|
span image_tag(at.image.variant(resize_to_limit: [100,100])) # This works fine
end
f.has_many :attachments, allow_destroy: true do |at|
at.input :name
at.input :image, as: :file, hint: image_tag(at.object.image) # The hint: bombs.
end
end
f.actions
end
I do not see the ActiveStorage activity in the logs, just ends in Completed 304
But I have no issue creating a new image attachments, images upload fine.
===
Workaround
The workaround to the image hint not showing is to use image_tag outside of the f.has_many block, which works if not as attractive as I would like.
The workaround to the new image not uploading is to delete the nested object first and then add a new one.