微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当我上传新视频时,它返回“无函数子句匹配”错误

如何解决当我上传新视频时,它返回“无函数子句匹配”错误

我正在将 Elixir 用于具有视频上传功能的新网站。视频保存到数据库,但上传后返回

no function clause matching in EngpinWeb.VideoController.persist_file/2

我正在使用 Elixir 1.11.2Phoenix 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 举报,一经查实,本站将立刻删除。