Ecto:将%Plug.Upload转换为虚拟字段以进行文件上载验证

时间:2015-11-17 05:25:48

标签: elixir phoenix-framework ecto

我希望只有在变更集有效且包含文件时才能触发文件上传。

是否有可能/一个好主意投一个%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

我尝试将:image设置为类型为:map的虚拟字段,但它不会强制转换`%Plug.Upload

schema "model" do
  field :image_url, :string
  field :image, :map, virtual: true
  timestamps
end

这只会导致消息Image is invalid

出现验证错误

2 个答案:

答案 0 :(得分:4)

为什么不定义以下功能(在单独的模块中):

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

在模型中有一个单独的功能,仅用于图像更改集。

def image_changeset(changeset, image_url) do
  put_change(changeset, :image_url, image_url)
end

答案 1 :(得分:2)

这样可以找到将虚拟字段的类型设置为cursor.execute("SELECT isnull(SOP30200.SOPNUMBE,''), isnull(SOP30200.docdate,'') from SOP30200 where SOP30200.docdate > ?", datetime.datetime(2015,1,1,0,0))

:any

现在当所有必填字段都存在且有文件时它会将其上传到云端,否则它只会正常创建/更新字段而不会在没有选择图像文件的情况下触发上传