Haito
Haito

Reputation: 2069

assign @changeset not available in eex template

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: enter image description here

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

Upvotes: 5

Views: 6285

Answers (2)

tblev
tblev

Reputation: 462

I had this same issue but with a partial...I was passing my changeset through my page#index like

 def index(conn, _params) do
    render(conn, "index.html", %{
      :other_stuff => true,
      :changeset =>  %Ecto.Changeset{}
    })
 end

Inside of my index.html.eex I had the partial rendering like:

<%= render("_dialog.html", conn: @conn) %>

The changeset needed to be passed into the partial the same as conn is, like:

<%= render("_dialog.html", conn: @conn, changeset: @changeset) %>

Upvotes: 0

Gazler
Gazler

Reputation: 84190

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

Upvotes: 8

Related Questions