如何解决当我上传新视频时,它返回“无函数子句匹配”错误
我正在将 Elixir 用于具有视频上传功能的新网站。视频保存到数据库,但上传后返回
no function clause matching in EngpinWeb.VideoController.persist_file/2
我正在使用 Elixir 1.11.2
和 Phoenix v1.5.7
defp persist_file(video,%{path: temp_path}) do
video_path = build_video_path(video)
unless File.exists?(video_path) do
video_path |> Path.dirname() |> File.mkdir_p()
File.copy!(temp_path,video_path)
end
这是整个控制器的其余部分
defmodule EngpinWeb.VideoController do
2 use EngpinWeb,:controller
3
4 import PhoenixVideoStream.Util,only: [build_video_path: 1]
5
6 alias Engpin.Teachers
7 alias Engpin.Teachers.Video
8
9
10 def index(conn,_params) do
11 videos = Teachers.list_videos()
12 render(conn,"index.html",videos: videos)
13 end
14
15 def new(conn,_params) do
16 changeset = Teachers.change_video(%Video{})
17 render(conn,"new.html",changeset: changeset)
18 end
19
20 def create(conn,%{"video" => video_params}) do
21 IO.inspect video_params
22 changeset = Video.changeset(%Video{},video_params)
23 case Teachers.create_video(video_params) do
24 {:ok,video} ->
25 persist_file(video,video_params["video_file_id"])
26
27 conn
28 |> put_flash(:info,"Video created successfully.")
29 |> redirect(to: Routes.video_path(conn,:show,:video))
30 {:error,changeset} ->
31 render(conn,changeset: changeset)
32 end
33 end
34 #def create(conn,%{"video" => video_params}) do
35 # case Teachers.create_video(video_params) do
36 # {:ok,video} ->
37 # conn
38 # |> put_flash(:info,"Video created successfully.")
39 # |> redirect(to: Routes.video_path(conn,video))
40
41 # {:error,%Ecto.Changeset{} = changeset} ->
42 # render(conn,changeset: changeset)
43 # end
44 #end
45
46 def show(conn,%{"id" => id}) do
47 video = Teachers.get_video!(id)
48 render(conn,"show.html",video: video)
49 end
50
51 def edit(conn,%{"id" => id}) do
52 video = Teachers.get_video!(id)
53 changeset = Teachers.change_video(video)
54 render(conn,"edit.html",video: video,changeset: changeset)
55 end
56
57 def update(conn,%{"id" => id,"video" => video_params}) do
58 video = Teachers.get_video!(id)
59
60 case Teachers.update_video(video,video_params) do
61 {:ok,video} ->
62 conn
63 |> put_flash(:info,"Video updated successfully.")
64 |> redirect(to: Routes.video_path(conn,video))
65
66 {:error,%Ecto.Changeset{} = changeset} ->
67 render(conn,changeset: changeset)
68 end
69 end
70
71 def delete(conn,%{"id" => id}) do
72 video = Teachers.get_video!(id)
73 {:ok,_video} = Teachers.delete_video(video)
74
75 conn
76 |> put_flash(:info,"Video deleted successfully.")
77 |> redirect(to: Routes.video_path(conn,:index))
78 end
79
80 defp persist_file(video,%{path: temp_path}) do
81 video_path = build_video_path(video)
82 unless File.exists?(video_path) do
83 video_path |> Path.dirname() |> File.mkdir_p()
84 File.copy!(temp_path,video_path)
85 end
86 end
87 end
解决方法
如果您的函数 defp persist_file(video,%{path: temp_path})
没有与您调用它的参数匹配的子句,那么找到该函数的调用点并查看传入的实际参数。在这种情况下,我认为发生的事情是第二个参数是一个带有字符串键而不是符号的映射,因此它与函数定义中的路径模式不匹配。
这是一个例子:
iex(1)> %{foo: :bar} = %{:foo => :bar}
%{foo: :bar}
iex(2)> %{foo: :bar} = %{"foo" => :bar}
** (MatchError) no match of right hand side value: %{"foo" => :bar}
在您的 persist_file
函数的特定情况下,可以这样尝试:
defp persist_file(video,%{"path" => temp_path}) do
video_path = build_video_path(video)
unless File.exists?(video_path) do
video_path |> Path.dirname() |> File.mkdir_p()
File.copy!(temp_path,video_path)
end
end
请注意,地图模式具有字符串键,就像第 20 行中 def create
中的地图模式一样。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。