Ecto验证和查询失败,没有错误

时间:2018-04-26 21:15:10

标签: elixir phoenix-framework ecto changeset

您好:)当我尝试使用表单插入数据时,我遇到了一些问题。

当我插入时,重定向有效,但会出现任何错误消息。

我的控制器如下:

defmodule HexProjectWeb.UserController do
  use HexProjectWeb, :controller

  import Ecto.Query

  alias HexProject.Accounts
  alias HexProject.Accounts.User
  alias HexProject.Gender

  def new(conn, _params) do
    genders = HexProject.Repo.all(
      from g in Gender,
      select: %{name: g.name, id: g.id}
    )

    changeset = Accounts.change_user(%User{})

    conn
    |> assign(:changeset, changeset)
    |> assign(:genders, genders)
    |> render("new.html")

    ##render(conn, "new.html", changeset: changeset)
  end

  def create(conn, %{"user" => user_params}) do
    case Accounts.create_user(user_params) do
      {:ok, user} ->
        conn
        |> put_flash(:info, "User created successfully.")
        |> redirect(to: user_path(conn, :show, user))
      {:error, %Ecto.Changeset{} = changeset} ->
        genders = HexProject.Repo.all(
          from g in Gender,
          select: %{name: g.name, id: g.id}
        )
        render(conn, "new.html", changeset: changeset, genders: genders)
    end
  end

  def show(conn, %{"id" => id}) do
    user = Accounts.get_user!(id)
    render(conn, "show.html", user: user)
  end
end

我的架构如下:

defmodule HexProject.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset
  alias HexProject.Accounts.User

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id

  schema "users" do
    field :avatar, :string
    field :birth_date, :date
    field :email, :string, size: 100
    field :firstname, :string, size: 30
    belongs_to :gender, HexProject.Gender
    field :lastname, :string, size: 30
    field :login, :string, size: 30
    field :newsletter, :boolean, default: false
    field :password, :string, size: 32
    field :pseudo, :string, size: 20
    field :token, :string, size: 32
    field :token_verif, :boolean, default: false

    timestamps(type: :utc_datetime)
  end

  @doc false
  def changeset(%User{} = user, attrs) do
    user
    |> cast(attrs, [:gender_id, :firstname, :lastname, :login, :password, :pseudo, :email, :birth_date, :token, :token_verif, :avatar, :newsletter])
    |> validate_required([:gender_id, :firstname, :lastname, :email])
    |> validate_length(:firstname, min: 2)
    |> validate_length(:lastname, min: 2)
    |> validate_length(:password, is: 32)
    |> validate_format(:email, ~r/.+@.+\..+/, [message: "Entrer un email valide avec @ et ."])
    |> unique_constraint(:email)
  end
end

我的查询都在我的accounts.ex中(我只向您显示插入查询,因为这就是这里的问题)

defmodule HexProject.Accounts do
  @moduledoc """
  The Accounts context.
  """

  import Ecto.Query, warn: false
  alias HexProject.Repo

  alias HexProject.Accounts.User

  @doc """
  Creates a user.

  ## Examples

      iex> create_user(%{field: value})
      {:ok, %User{}}

      iex> create_user(%{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def create_user(attrs \\ %{}) do
    %User{}
    |> User.changeset(attrs)
    |> Repo.insert()
  end

  @doc """
  Returns an `%Ecto.Changeset{}` for tracking user changes.

  ## Examples

      iex> change_user(user)
      %Ecto.Changeset{source: %User{}}

  """
  def change_user(%User{} = user) do
    User.changeset(user, %{})
  end
end

和我的表格:

<%= form_for @changeset, user_path(@conn, :create), fn f -> %>
    <%= select f, :genders, Enum.map(@genders, &{&1.name, &1.id}), prompt: "Sexe" %>
        <label>
            Email: <%= text_input f, :mail %>
        </label>

        <label>
            Lastname: <%= text_input f, :lastname %>
        </label>

        <label>
            Firstname: <%= text_input f, :firstname %>
        </label>

        <label>
            Newsletter: <%= checkbox f, :newsletter %>
        </label>

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

即使我提供了错误的值,表单也会提交,并且不会出现错误。我注意到它失败了,因为它在提交后呈现了包含所有值的表单(当然没有插入数据)。

感谢您的支持。

1 个答案:

答案 0 :(得分:0)

如果无法插入记录,它将执行以下代码:

 {:error, %Ecto.Changeset{} = changeset} ->
    genders = HexProject.Repo.all(
      from g in Gender,
      select: %{name: g.name, id: g.id}
    )
    render(conn, "new.html", changeset: changeset, genders: genders)

是的,它只是呈现new.html页面,其中包含从提交的changeset中获取的所有值。如果你想渲染一条错误信息,你确实应该instruct phoenix to do that,没有魔法:

 {:error, %Ecto.Changeset{} = changeset} ->
    genders = HexProject.Repo.all(
      from g in Gender,
      select: %{name: g.name, id: g.id}
    )
    conn
    |> put_flash(:error, "User was not created.")
    |> render("new.html", changeset: changeset, genders: genders)