我试图将多个图像附加到一个字段。我可以轻松地创建与图像模型的关联,但我想看看如何使用地图/数组字段完成相同的操作。
该模型如下所示。
schema "users" do
field :images, {:array}
end
def changeset(user, params \\ :invalid) do
user
|> cast(params, [:name])
|> cast_attachments(params, [:avatar])
|> validate_required([:name, :avatar])
end
答案 0 :(得分:0)
据我所知,不支持直接使用数组/地图。
您可以使用嵌入式架构将其另存为地图。
这应该有效:
defmodule Image do
use Ecto.Schema
use Arc.Ecto.Schema
import Ecto
import Ecto.Changeset
@required_fields ~w(file)
@optional_fields ~w()
embedded_schema do
field :file, MyApp.UserImage.Type
end
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> cast_attachments(params, [:file])
end
end
defmodule User do
use Ecto.Schema
import Ecto
import Ecto.Changeset
schema "projects" do
field :code, :string
embeds_many :images, MyApp.Image
end
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> cast_embed(:images) # invoke changeset in the embed module
end
end
然后你可以像这样使用它
images = [%{file: "image1"}, %{file: "image2"}]
changeset = User.changeset(user, %{"images" => images})
new_user = Repo.update!(changeset)
urls = Enum.map new_user.images, fn image ->
UserImage.urls({image.file, new_user})
end
唯一的缺点是,在保存图像时,您无法在scope
模块中使用UserImage
参数。这是因为当您调用cast_attachments函数时,arc_ecto将模型用作scope
,现在您在调用函数时没有原始模型(User)。
在迁移文件中,您应该将图片字段定义为:map