我正试图在页面上做一个简单的登录。每当我尝试将我的页面路由到用户注册时,我收到以下错误。
UndefinedFunctionError at GET /users/new
function Ecto.Changeset.fetch/2 is undefined or private. Did you mean one of:
* fetch_change/2
* fetch_field/2
这个错误似乎来自Changeset,因为每当我注释掉我的Changeset并只渲染一个空的html页面时它就可以运行。任何帮助将不胜感激。
网/控制器/ user_controller.ex
defmodule Test.UserController do
use Test.Web, :controller
alias Test.User
def new(conn, params) do
changeset = User.changeset(%User{})
render conn, "new.html", changeset
end
def show(conn, %{"user_id_hash" => user_id_hash}) do
render conn, "user_index.html", %{layout: {Test.LayoutView, "react.html"}}
end
def create(conn, %{"user" => user_params}) do
changeset = User.changeset(%User{}, user_params)
case Repo.insert(changeset) do
{:ok, user} ->
conn
|> put_flash(:info, "#{user.username} thank you for signing up please check your email to confirm your account.")
|> redirect(to: page_path(conn, :index))
{:error, changeset}->
render(conn, "new.html", changeset: changeset)
end
end
end
然后是我在web / models / user.ex中的模型
defmodule Test.User do
use Test.Web, :model
#Allows us to query the Database as Repo.
alias Test.Repo
#Allows us to use our User model as User.(function)
alias Test.User
#These are
@fields ~w(username email password encrypted_password user_id_hash password_confirmation)a
#These are the required fields as atoms for the validate_required method.
@required_fields_atoms ~w(username email password password_confirmation)a
schema "users" do
field :username, :string
field :email, :string
field :encrypted_password, :string
field :user_id_hash, :string
field :account_confirmed, :boolean
field :confirmation_hash, :string
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
timestamps()
end
@doc """
Builds a changeset based on the `struct` and `params`.
"""
def changeset(struct, params \\ %{}) do
struct
|> cast(params, @fields)
|> validate_required(@required_fields)
|> validate_length(:username, min: 6, max: 32)
|> validate_length(:password, min: 8, max: 100)
|> validate_confirmation(:password, message: "does not match password")
|> put_pass_hash()
end
def generate_confirmation_token() do
rand_string = random_string(26)
end
defp put_pass_hash(changeset) do
case changeset do
%Ecto.Changeset{valid?: true, changes: %{password: pass}} ->
put_change(changeset, :encrypted_password, Comeonin.Bcrypt.hashpwsalt(pass))
_ -> changeset
end
end
defp random_string(length) do
:crypto.strong_rand_bytes(length) |> Base.url_encode64 |> binary_part(0, length)
end
end
运行程序时,错误说它来自
Test.UserController.action/2 (test)
web/controllers/user_controller.ex (line 1)
如果有人可以提供帮助,我永远不会打电话给fetch功能。
编辑添加了堆栈跟踪
[error] #PID<0.365.0> running Test.Endpoint terminated
Server: my-name.c9users.io:8081 (http)
Request: GET /users/new
** (exit) an exception was raised:
** (UndefinedFunctionError) function Ecto.Changeset.fetch/2 is undefined or private. Did you mean one of:
* fetch_change/2
* fetch_field/2
(ecto) Ecto.Changeset.fetch(#Ecto.Changeset<action: nil, changes: %{}, errors: [username: {"can't be blank", []}], data: #Test.User<>, valid?: false>, :conn)
(phoenix_html) lib/phoenix_html/engine.ex:98: Phoenix.HTML.Engine.fetch_assign/2
(test) web/templates/layout/app.html.eex:11: Test.LayoutView."app.html"/1
(phoenix) lib/phoenix/view.ex:335: Phoenix.View.render_to_iodata/3
(phoenix) lib/phoenix/controller.ex:641: Phoenix.Controller.do_render/4
(test) web/controllers/user_controller.ex:1: Test.UserController.action/2
(test) web/controllers/user_controller.ex:1: Test.UserController.phoenix_controller_pipeline/2
(test) lib/test/endpoint.ex:1: Test.Endpoint.instrument/4
(test) lib/phoenix/router.ex:261: Test.Router.dispatch/2
(test) web/router.ex:1: Test.Router.do_call/2
(test) lib/test/endpoint.ex:1: Test.Endpoint.phoenix_pipeline/1
(test) lib/plug/debugger.ex:93: Test.Endpoint."call (overridable 3)"/2
(test) lib/test/endpoint.ex:1: Test.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
^C
答案 0 :(得分:7)
在Test.UserController
中,这个:
render conn, "new.html", changeset
应该是
render conn, "new.html", changeset: changeset
您获得的奇怪错误是因为Phoenix templates fetch @
variables using Dict.fetch
。在这种情况下,您最有可能在模板中的某个位置使用@conn
,并且它正在尝试运行Dict.fetch(changeset, :conn)
,changeset.__struct__.fetch(changeset, :conn)
委托给changeset
Ecto.Changeset.fetch(changeset, :conn)
是一个结构,最后调用TestID StudentID ComponentID Score
-------------------------------------
14919 3445 1 20
14919 3445 4 17
14919 3445 8 20
14919 3445 11 19
14919 3445 13 19
11339 3448 1 15
11339 3448 4 23
11339 3448 8 23
**11339 3448 11 22**
11339 3448 13 20
**14773 3448 1 20**
14773 3448 4 21
**14773 3448 8 23**
14773 3448 11 21
**14773 3448 13 21**
。