我正在尝试创建一个基本的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
答案 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