assign @changeset not available in eex template

2019-06-26 04:31发布

问题:

I am trying to learn the Phoenix's Form system with including the Ecto.Model's but i have encountered a problem that i can't pass. I have created a form:

<div class="jumbotron">
  <%= form_for @changeset, user_path(@conn, :create), fn f -> %>
    <label>
      Login: <%= text_input f, :login %>
    </label>
    <label>
      Password: <%= password_input f, :password %>
    </label>
    <label>
      Name: <%= text_input f, :name %>
    </label>
    <label>
      Surname: <%= text_input f, :name %>
    </label>
    <label>
      Email: <%= email_input f, :name %>
    </label>
    <label>
      Class: <%= text_input f, :name %>
    </label>
    <label>
      Phone: <%= text_input f, :name %>
    </label>

    <%= submit "Submit" %>
  <% end %>
</div>

That is being served by Controller:

  def index(conn, _params) do
    changeset = User.changeset(%User{})
    render conn, "index.html", changeset: changeset
  end

  def create(conn, _params) do
    IO.inspect(_params)
    render conn, "index.html"
  end

And the model:

defmodule Kpsz.Model.User do
  use Kpsz.Web, :model

  schema "users" do
    field :login, :string
    field :password, :string
    field :email, :string

    field :role, :integer

    field :name, :string
    field :surname, :string
    field :class, :string
    field :phone_number, :string

    has_many :presences, Kpsz.Model.Presence
  end

  @required_fields ~w(login,password,email,name,surname,class,phone_number)
  @optional_fields ~w(role)

  def changeset(user, params \\ :empty) do
    case params do
      :empty -> cast(user,params, ~w(),~w())
      _ -> user
        |> cast(params, @required_fields, @optional_fields)
        |> validate_format(:email, ~r/@/)
        |> unique_constraint(:email)
    end
  end

end

I have pattern matched the params, because i was getting bunch of errors while creating empty changeset for passing it to the form. Is there any better way around it?

And error I am getting after submiting the form:

Can anyone point out what I am doing wrong and give some info how to fix it?

回答1:

You are rendering the same view and template from both actions.

This line:

<%= form_for @changeset, user_path(@conn, :create), fn f -> %>

References @changeset which is expected to be passed to your Eex template via assigns. In a phoenix controller you do this by calling:

render(conn, template, assigns)

In your case you are passing the changeset on index but not on create. Normally your form will be rendered in the new function and the params will be used in the changeset function in the create function.

Consider generating this code to see how it works:

mix phoenix.gen.html User name surname email age:integer