1

我正在尝试创建一个基本的 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(user) 似乎返回了一些东西,但不是错误 - 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
4

1 回答 1

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
于 2015-03-12T23:08:30.200 回答