I’m struggling to create a form where the user should be able to upload multiple images and add descriptions for each of them. The idea is to add them as embeds to a resource (in this case a post resource).
defmodule MyApp.Post do
use Ecto.Schema
schema "posts" do
field :title, :string
field :content, :string
embeds_many :images, Image
end
end
defmodule MyApp.Post.Image do
use Ecto.Schema
embedded_schema do
field :image_url, :string # For simplicity. In reality it's a waffle upload
field :description, :string
end
end
So far I set up a basic form with a live file upload, that shows a preview of the uploaded files, but I don’t know how to progress from here. Any ideas?
Here are the docs—They are detailed and short. I basically forget how to do image uploads every time I start a new project and I essentially copy paste everything on that page and it works beautifully (you just have to change the references to my_app). I’ve never used Waffle, though.
defp assign_media_params(entries, params, ref_positions) do
for entry <- entries do
new_ref = Map.get(ref_positions, entry.ref, String.to_integer(entry.ref))
|> Integer.to_string()
%{
ref: new_ref,
url_original: Path.join(S3Upload.s3_host(), S3Upload.s3_key(entry, "full")),
url_preview: Path.join(S3Upload.s3_host(), S3Upload.s3_key(entry, "prev")),
url_blur: Path.join(S3Upload.s3_host(), S3Upload.s3_key(entry, "blur")),
privacy: params["privacy"],
warning: Map.get(params, "warning_#{new_ref}", "SFW"),
description: Map.get(params, "description_#{new_ref}", "")
}
end
end
The new_ref is something external. I can change the order of images in the socket and create new refs so they appear in that order. You would just use the default entry.ref if you want to do it in the standard order.
For future reference, your forms’ fields don’t have to mirror your Ecto schemas, the one you persist. You can have specialised data structures for your views and translate them to params for your business logic layer and then translate to Ecto schemas.