【问题标题】:phoenix undefined function changeset/3凤凰未定义函数变更集/3
【发布时间】:2016-09-18 12:00:13
【问题描述】:

我研究框架phoenix。 是将存储在云存储中的图像模型。创建图像时,我计算文件的哈希值,并将其作为:name。我做了一个模型、控制器和视图。但我不明白为什么会收到错误:

== Compilation error on file web/models/image.ex ==
** (CompileError) web/models/image.ex:26: undefined function changeset/3
    (stdlib) lists.erl:1338: :lists.foreach/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:116: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1

我查看了你所有的代码,但没有找到我用三个参数调用 Image.changeset 的地方。 我的图片.ex:

defmodule Blog.Image do
  use Blog.Web, :model

  schema "images" do
    field :name, :string
    field :original_name, :string
    field :filename, :string, virtual: true

    timestamps
  end

  @required_fields ~w(
    name
    original_name
    filename
  )
  @optional_fields ~w()

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @required_fields, @optional_fields)
  end

  def create_changeset(struct, params \\ %{}) do
    struct
    |> changeset(struct, params)
    |> generate_name_hash
  end

  defp generate_name_hash(changeset) do
    put_change(changeset, :name, gen_hash_name(changeset[:filename]))
  end

  defp gen_hash_name(filename) do
    hash_name = :crypto.hash(:sha256, File.read(filename))
    |> Base.encode16
    "/"<>slice(hash_name, 0, 2)<>"/"<>slice(hash_name, 2, 2)<>"/"<>slice(hash_name, 4, 2)
  end

end

我的 image_controller.ex:

defmodule Blog.ImageController do
  use Blog.Web, :controller
  plug Addict.Plugs.Authenticated when action in [:new, :create]

  def new(conn, _params) do
    changeset = Blog.Image.changeset(%Blog.Image{})
    render conn, "new.html", changeset: changeset
  end

  def create(conn, %{"image" => image_params}) do
    full_image_params = %{filename: image_params["image"].path, original_name: image_params["image"].filename}
    changeset = Blog.Image.create_changeset(%Blog.Image{}, full_image_params)
    case Blog.Repo.insert(changeset) do
      {:ok, image} ->
        conn
        |> put_flash(:info, "Image created successfully.")
        |> redirect(to: image_path(conn, :show, image))
      {:error, changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end
end

我的 new.html.eex:

<%= form_for @changeset, image_path(@conn, :create), [role: "form", multipart: true], fn f -> %>
  <div class="form-group">
    <%= label f, :image, class: "control-label" %>
    <%= file_input f, :image, class: "form-control" %>
    <%= error_tag f, :image %>
  </div>
  <div class="container">
    <div class="form-group">
      <%= submit "Submit", class: "btn btn-default" %>
    </div>
  </div>
<% end %>

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    我相信这一点:

     def create_changeset(struct, params \\ %{}) do
        struct
        |> changeset(struct, params)
        |> generate_name_hash
      end
    

    应该是

     def create_changeset(struct, params \\ %{}) do
        struct
        |> changeset(params)
        |> generate_name_hash
      end
    

    因为|&gt; 运算符将其左侧的任何内容作为第一个参数传递给右侧的函数。所以你基本上是在做changeset(struct, struct, params)

    【讨论】:

      【解决方案2】:

      堆栈跟踪会告诉您错误的确切位置: ** (CompileError) web/models/image.ex:26: undefined function changeset/3。

      我相信您正在尝试使用 cast 函数,因为 changeset 函数本身并不存在于 Ecto changesets 中。此外,cast 的数量为 3,因此您缺少一个论点。

      在第 26 行更改:

      def create_changeset(struct, params \\ %{}) do
        struct
        |> changeset(struct, params)
        |> generate_name_hash
      end
      

      对此:

      def create_changeset(struct, params \\ %{}) do
        struct
        |> cast(params, [:name, :original_name, :filename])   #<---- 3rd arg. = 'allowed'
        |> generate_name_hash
      end
      

      其中cast 函数需要三个参数cast(data, params, allowed)。所有未明确允许的参数都将被忽略。

      正如 Mchl 所说,函数的结果将传递给管道操作中的下一个函数的 FIRST 参数(在此特定帖子中,您无需显式传递 struct)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-30
        • 2016-05-03
        • 1970-01-01
        相关资源
        最近更新 更多