Ecto验证失败,没有错误

时间:2015-03-11 02:49:43

标签: elixir phoenix-framework ecto

我正在尝试创建一个基本的CRUD应用,但我在验证方面遇到了问题。这是我的控制器动作:

def update(conn, %{"id" => id, "user" => params}) do
  case Repo.get(User, String.to_integer(id)) do
    user when is_map(user) ->
      user = Map.merge(user, atomize_keys(params))
      case User.validate(user) do
        [] ->
          Repo.update(user)
          redirect conn, to: user_path(:show, user.id)
        errors ->
          text conn, "Validation Failed!"
          ##render conn, "editform.html", user: user, errors: errors
      end
    _ ->
      redirect conn, to: user_path(:index)
  end
end

和我的模特:

defmodule MyApp.User do
  use Ecto.Model
  validate user, 
   email: present()

  schema "users" do
   field :first_name, :string
   field :last_name, :string
   field :email, :string
   field :created_at, :datetime, default: Ecto.DateTime.local
   field :updated_at, :datetime, default: Ecto.DateTime.local
  end
end

User.validate(用户)似乎正在返回一些东西,但不是错误 - 在form.html中没有出现错误。我在这里错过了什么?这可能是atomize_keys()函数的问题吗?这是那个:

defp atomize_keys(struct) do
  Enum.reduce struct, %{}, fn({k, v}, map) 
  -> Map.put(map,  String.to_atom(k), v) end
end

1 个答案:

答案 0 :(得分:1)

这是你的配置应该是这样的:

# config/config.exs
use Mix.Config

# Your endpoint config and your logger config go here...

# DB config:
config :my_app, MyApp.Repo,
   adapter: Ecto.Adapters.Postgres,
   database: "myapp",
   username: "username",
   password: "password",
   server: "localhost"

然后你的模型看起来像这样:

defmodule MyApp.User do
  use Ecto.Model

  schema "users" do
    field :first_name, :string
    field :last_name, :string
    field :email, :string
    field :created_at, :datetime, default: Ecto.DateTime.local
    field :updated_at, :datetime, default: Ecto.DateTime.local
  end

  def changeset(params, :create) do
    # Read the docs for Ecto.Changeset.cast, by including email in the second argument, it becomes required, the third argument are the optional arguments. Anything not in these two lists will be dropped out of the passed in params.
    # User validate_change for other custom validations.
    %User{}
    |> cast(params, ~w(email), ~(first_name last_name)
    |> validate_unique(:email, on: MyApp.Repo)
  end

  def changeset(params, :update, user) do
    user
    |> cast(params, [], ~w(email first_name last_name))
    |> validate_unique(:email, on: MyApp.Repo)
  end
end

此模型代码的好处意味着您的控制器可能如下所示:

def update(conn, %{"id" => id, "user" => params}) do
  user = MyApp.Repo.get(User, id)

  case user do
    %MyApp.User{} ->
      changeset = User.changeset(params, :update, user)

      if changeset.valid? do
        Repo.update(changeset)
        redirect conn, to: user_path(:show, user.id)
      else
        render conn "editform.html", user: user, errors: changeset.errors
      end
    _ ->
      redirect conn, to: user_path(:index)
  end
end