在 Elixir 中使用 Acr 上传文件到本地
File Upload to Local using Acr in Elixir
我正在使用 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
但是,我收到一条错误消息 "no function clause matching in Arc.Actions.Store.store"。
堆栈跟踪如下:
** (FunctionClauseError) no function clause matching in 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, 8, 0, 0, 0,
58, 0, 50, 1, 2, 0, 20, 0, 0, 0, 198, 2, 0, 0, 15, 1, 2, 0, 10, 0, 0,
0, 218, 2, 0, 0, 1, 1, ...>>, filename: "image.png"}})
有人帮忙吗?
你的代码
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
我正在使用 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
但是,我收到一条错误消息 "no function clause matching in Arc.Actions.Store.store"。
堆栈跟踪如下:
** (FunctionClauseError) no function clause matching in 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, 8, 0, 0, 0, 58, 0, 50, 1, 2, 0, 20, 0, 0, 0, 198, 2, 0, 0, 15, 1, 2, 0, 10, 0, 0, 0, 218, 2, 0, 0, 1, 1, ...>>, filename: "image.png"}})
有人帮忙吗?
你的代码
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