使用Elix中的Acr将文件上载到本地

问题描述 投票:2回答:1

我正在使用Arc.Definition(https://github.com/stavro/arc)将图像上传到本地存储。

我的file_service.ex如下:

defmodule MyApp.FileService do
  use Arc.Definition
  use Arc.Ecto.Definition

  @image_types ~w(.jpg .jpeg .png .gif)
  @versions [:original]
  @default_filename "image.png"

  @heights %{
    medium: 400
  }

  @widths %{
    medium: 400
  }

  def __storage, do: Arc.Storage.Local

  def upload_image(%Plug.Upload{} = image, resource_type, resource_id) do
    store({%Plug.Upload{path: image.path, filename: @default_filename},
      %{resource_type: resource_type, resource_id: resource_id}})
  end

  def upload_base64_image(base64_image, resource_type, resource_id) do
    store({%{filename: @default_filename, binary: base64_image_to_binary(base64_image)}})
  end 

  def delete_file(image_url, resource) do
    delete({image_url, resource})
  end

  defp base64_image_to_binary("data:image/" <> rest) do
    rest
    |> String.replace("\n", "")
    |> String.split(",")
    |> Enum.at(1)
    |> Base.decode64!
  end
  defp base64_image_to_binary(base64_image) do
    base64_image
    |> String.replace("\n", "")
    |> Base.decode64!
  end
end

但是,我收到一条错误,说“在Arc.Actions.Store.store中没有匹配的函数子句”。

堆栈跟踪如下:

**(FunctionClauseError)在Arc.Actions.Store.store/2(arc)中没有函数子句匹配lib / arc / actions / store.ex:8:Arc.Actions.Store.store(MyApp.FileService,{%{binary :<< 255,216,255,225,3,48,69,120,105,102,0,0,73,73,42,0,0,0,0,0,58,0,50,1 ,2,0,20,0,0,0,198,2,0,0,15,2,0,10,0,0,0,218,2,0,0,1,1,.... .. >>,文件名:“image.png”}})

有人,请帮忙吗?

file-upload elixir plug
1个回答
1
投票

你的代码

 def upload_base64_image(base64_image, resource_type, resource_id) do
    store({%{filename: @default_filename, binary: base64_image_to_binary(base64_image)}})
  end 

store使用错误。

它只接受tuple(file, scope)filepath(map)

所以它应该是:store(%{filename: @default_filename, binary: base64_image_to_binary(base64_image)})

请参阅github的示例:

# Store a file from a connection body
{:ok, data, _conn} = Plug.Conn.read_body(conn)
Avatar.store(%{filename: "file.png", binary: data})

我通过阅读traceback和arc的商店实现来解决这个问题:

  def store(definition, {file, scope}) when is_binary(file) or is_map(file) do
    put(definition, {Arc.File.new(file), scope})
  end

  def store(definition, filepath) when is_binary(filepath) or is_map(filepath) do
    store(definition, {filepath, nil})
  end
© www.soinside.com 2019 - 2024. All rights reserved.