assign @changeset not available in eex template
Asked Answered
W

2

5

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?

Wobble answered 29/11, 2015 at 12:54 Comment(0)
C
8

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
Clamshell answered 29/11, 2015 at 13:0 Comment(4)
"** (Mix) The task ecto.gen.html could not be found"Wobble
@Wobble Sorry - that should have been mix phoenix.gen.htmlClamshell
what type should i write for datetime? (i mean i havo to do date: what)Wobble
:datetime should work github.com/phoenixframework/phoenix/blob/v1.0.4/lib/mix/tasks/… e.g. age:integer some_time:datetimeClamshell
A
0

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) %>
Allnight answered 23/6, 2021 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.