Mie*_*yba 2 elixir ecto phoenix-framework
根据凤凰文件:
insert(Ecto.Schema.t | Ecto.Changeset.t,Keyword.t):: {:ok,Ecto.Schema.t} | {:error,Ecto.Changeset.t}
插入模型或变更集.
在给出模型的情况下,模型将转换为变更集,其中所有模型非虚拟字段都作为变更集的一部分.通过直接调用Ecto.Changeset.change/2来完成此转换.
如果给出变更集,则变更集中的更改将与模型字段合并,并且所有变更都将发送到数据库.
如果在给定模型中注册了任何before_insert或after_insert回调,则将使用changeset调用它们.
如果已成功插入模型,则返回{:ok,model};如果存在验证或已知约束错误,则返回{:error,changeset}.
defmodule Dollar.User do
use Dollar.Web, :model
schema "users" do
field :username, :string
field :sms_number, :string
field :email, :string
timestamps
end
@required_fields ~w(sms_number)
@optional_fields ~w(username email)
@doc """
Creates a changeset based on the `model` and `params`.
If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(user, params \\ :empty) do
user
|> cast(params, @required_fields, @optional_fields)
|> validate_length(:sms_number, is: 10)
|> unique_constraint(:sms_number)
|> unique_constraint(:username)
end
end
Run Code Online (Sandbox Code Playgroud)
Repo.insert(%User{})
=> {:error, ... }
Run Code Online (Sandbox Code Playgroud)
我预计会出错,因为这sms_number是必需的.
[debug] INSERT INTO "users" ("inserted_at", "updated_at", "email", "sms_number", "username") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [{{2016, 3, 19}, {15, 13, 5, 0}}, {{2016, 3, 19}, {15, 13, 5, 0}}, nil, nil, nil] OK query=1.5ms
%Dollar.User{__meta__: #Ecto.Schema.Metadata<:loaded>, email: nil, id: 7,
inserted_at: #Ecto.DateTime<2016-03-19T15:13:05Z>, sms_number: nil,
updated_at: #Ecto.DateTime<2016-03-19T15:13:05Z>, username: nil}
Run Code Online (Sandbox Code Playgroud)
记录存储在数据库中
我究竟做错了什么?
当您尝试直接插入模型中定义的struct时,changeset根本不会调用该函数.%User{}只是模块中的结构,ecto对此模块中定义的函数一无所知.您可以删除changeset功能,Repo.insert仍然可以使用.
changesetfunction是您的自定义验证码.您粘贴的文档声明另一个函数被调用:Ecto.Changeset.change/2.它创建一个默认有效的变更集,并且不需要字段.
你可以自己试试:
changeset = Ecto.Changeset.change %User{}
changeset.required # []
changeset.valid? # true
new_changeset = User.changeset changeset
new_changeset.required # [:sms_number]
new_changeset.valid? # false
Run Code Online (Sandbox Code Playgroud)
始终在插入数据库之前运行自定义验证,并使用Repo.insert变更集而不是原始结构.在迁移中使用非空约束强制数据库本身的必需字段可能也是一个好主意:
add :username, :string, null: false
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2144 次 |
| 最近记录: |