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

问题描述

我正在将 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 中的地图模式一样。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...