[英]Ecto: Casting %Plug.Upload to virtual field for file upload validations
I would like to be able to trigger a file upload only when a changeset is valid and contains a file. 我希望只有在变更集有效且包含文件时才能触发文件上传。
Is it possible/A good idea to cast a %Plug.Upload
eg 是否有可能/一个好主意施放
%Plug.Upload
例如
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> save_image
end
defp save_image(changeset) do
case changeset do
%Ecto.Changeset{valid?: true, changes: %{image: image}} ->
%{ "url" => "http://" <> image_url } = Cloudinary.upload(image)
put_change(changeset, :image_url, image_url)
_ ->
changeset
end
end
I have tried to set :image
to a virtual field with type :map
but it won't cast the ` %Plug.Upload 我试图将
:image
设置为类型为:map
的虚拟字段,但它不会强制转换`%Plug.Upload
schema "model" do
field :image_url, :string
field :image, :map, virtual: true
timestamps
end
This just cause a validation error with the message Image is invalid
这只是导致验证错误,消息
Image is invalid
Why not define the following function (in a separate module): 为什么不定义以下函数(在单独的模块中):
def save_image(model, params) do
changeset = Model.changeset(model, params)
case changeset.valid? do
true ->
%{ "url" => "http://" <> image_url } = Cloudinary.upload(params["file"])
Model.image_changeset(changeset, image)
_ -> changeset
end
end
And have a separate function in your model just for the image changeset. 并且只为图像更改集在模型中有一个单独的功能。
def image_changeset(changeset, image_url) do
put_change(changeset, :image_url, image_url)
end
This will work just find be setting the type of the virtual field to :any
这将只是找到将虚拟字段的类型设置为
:any
schema "model" do
field :image_url, :string
field :image, :any, virtual: true
timestamps
end
Now when all the required fields are present and there is a file it will upload it to the cloud otherwise it will just create/update the fields as normally without triggering an upload if no image file was selected 现在,当所有必填字段都存在且有文件时,它会将其上传到云端,否则它只会正常创建/更新字段,如果没有选择图像文件则不会触发上传
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.