2016-07-12 7 views
0

Ich versuche, eine einfache Anmeldeseite zu machen. Immer wenn ich versuche, meine Seite an die Benutzeranmeldung weiterzuleiten, erhalte ich den folgenden Fehler.Fehler Ecto.Changeset.fetch/2 ist nicht definiert oder privat

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 

Dieser Fehler wurde wahrscheinlich aus dem Changeset zu kommen, wenn ich meine Changeset Kommentar und machen nur eine leere HTML-Seite es funktioniert. Jede Hilfe würde sehr geschätzt werden.

web/controllers/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 

Dann für mein Modell in 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 

Wenn das Programm läuft der Fehler sagen, es wird von

kommenden
Test.UserController.action/2 (test) 
web/controllers/user_controller.ex (line 1) 

Ich rufe nie eine Abruffunktion wäre sehr verpflichtet, wenn jemand helfen könnte.

EDIT Hinzugefügt wurde die Stack-Trace

[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

Können Sie bitte die genaue Stapelverfolgung, die von Elixir gedruckt wurde, zur Frage hinzufügen? – Dogbert

+0

@Dogbert, ich habe die Frage mit dem Stack-Trace aktualisiert. – cogle

Antwort

7

In Test.UserController, dieses:

render conn, "new.html", changeset 

render conn, "new.html", changeset: changeset 

Die seltsame Fehler ist, weil Phoenix templates fetch @ variables using Dict.fetch Sie bekommen sollte. In diesem Fall verwenden Sie höchstwahrscheinlich @conn irgendwo in Ihrer Vorlage, und es versucht Dict.fetch(changeset, :conn) auszuführen, delegiert an changeset.__struct__.fetch(changeset, :conn) als changeset ist eine Struktur, und landet schließlich Aufruf Ecto.Changeset.fetch(changeset, :conn).

+0

Ich habe fast das gleiche Problem, und habe seit einer Stunde ohne irgendwelche Fehler - Sie haben meinen Tag gerettet. Vielen Dank! – Nick

Verwandte Themen