Rails has internal patterns for which it generates tables to handle polymorphic associations
has_one_attached :document
has_many_attached :pictures
has_rich_text :body
However, this polymorphism is hard to wrangle with the polymorphism that the mobility
gem provides, where one would declare:
translates :caption, type: :string
translates :description, type: :text
Firstly, there is an unexpected behaviour in migrations: migrating backwards before migration set-up for ActiveStorage, the tables were found to not be deleted. Migrating + restarting the server = objects were still being rendered. Only purges delete them.
I cannot fathom where I went wrong, not having modified the migration. I do notice however, for a Rails 7 application, that the class is declared as
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
maybe it works on up but not down...
The following does create columns that render, can be queried and updated via the console.
class UpdateActiveStorageTables < ActiveRecord::Migration[7.0]
def change
add_column :active_storage_blobs, :caption, :string
add_column :active_storage_blobs, :description, :text
end
end
The controller action can update the blob
def add_image
images = params[:individual][:image]
if images
images.each do |image|
@individual.images.attach(image)
end
end
@individual.save
new_image = @individual.images.last # in the hope of no near-simultaneous addition of an image to said user
new_image.blob.update(caption: params[:individual][:caption], description: params[:individual][:description])
end
yes this is somewhat odd, but with the form, the added attributes (caption and description) are not part of the image data array
Can one declare this at a model level for Mobility and integrate Mobility into this action (and how, if so)?
An alternative would be to create a new class, polymorphic assuming multiple classes use ActiveStorage, to create attributes that belong to the attachment, translate those as subsequent data inputs to the attachment creation.
But how would on define the migration and model (belongs_to ActiveStorage::Attachment
?) to create such classes?
On my opinion has_one_attached
is always more preferable over has_many_attached
because you can add to "parent" model any needed columns, sort by them, etc.
class Picture < ApplicationRecord
extend Mobility
belongs_to :imageable, polymorphic: true
has_one_attached :file
translates :caption, type: :string
translates :description, type: :text
end
class User < ApplicationRecord
has_many :pictures, as: :imageable
end
In this case you can use these caption
or description
for Picture
model, not for blobs