put_assoc 需要验证
Validate required for put_assoc
在我的 phoenix 项目中,我有一个通过联接链接的帖子和标签架构 table
schema "posts" do
field :title, :string
field :body, :string
many_to_many :tags, App.Tag, join_through: App.PostsTags , on_replace: :delete
timestamps()
end?
如何使用 put_assoc 确保标签存在?
def changeset(struct, params \ %{}) do
struct
|> cast(params, [:title, :body])
|> put_assoc(:tags, parse_tags(params), required: true)
|> validate_required([:title, :body, :tags])
end
两者都需要:put_assoc 上的 true 和添加 :tags 以验证 required 并没有像我想象的那样工作。
validate_length/3
可用于检查 tags
列表是否为空:
Post 架构:
defmodule MyApp.Blog.Post do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Blog.Post
schema "blog_posts" do
field :body, :string
field :title, :string
many_to_many :tags, MyApp.Blog.Tag, join_through: "blog_posts_tags"
timestamps()
end
@doc false
def changeset(%Post{} = post, attrs) do
post
|> cast(attrs, [:title, :body])
|> put_assoc(:tags, attrs[:tags], required: true)
|> validate_required([:title, :body])
|> validate_length(:tags, min: 1)
end
end
标记架构:
defmodule MyApp.Blog.Tag do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Blog.Tag
schema "blog_tags" do
field :name, :string
timestamps()
end
@doc false
def changeset(%Tag{} = tag, attrs) do
tag
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
存在 tags
时验证成功:
iex(16)> Post.changeset(%Post{}, %{title: "Ecto Many-to-Many", body: "Lots of words", tags: [%{name: "tech"}]})
#Ecto.Changeset<action: nil,
changes: %{body: "Lots of words",
tags: [#Ecto.Changeset<action: :insert, changes: %{name: "tech"}, errors: [],
data: #MyApp.Blog.Tag<>, valid?: true>], title: "Ecto Many-to-Many"},
errors: [], data: #MyApp.Blog.Post<>, valid?: true>
当 tags
为空时产生错误:
iex(17)> Post.changeset(%Post{}, %{title: "Ecto Many-to-Many", body: "Lots of words", tags: []})
#Ecto.Changeset<action: nil,
changes: %{body: "Lots of words", tags: [], title: "Ecto Many-to-Many"},
errors: [tags: {"should have at least %{count} item(s)",
[count: 1, validation: :length, min: 1]}], data: #MyApp.Blog.Post<>,
valid?: false>
当 tags
为 nil 时产生错误:
iex(18)> Post.changeset(%Post{}, %{title: "Ecto Many-to-Many", body: "Lots of words"})
#Ecto.Changeset<action: nil,
changes: %{body: "Lots of words", title: "Ecto Many-to-Many"},
errors: [tags: {"is invalid", [type: {:array, :map}]}],
data: #MyApp.Blog.Post<>, valid?: false>
在我的 phoenix 项目中,我有一个通过联接链接的帖子和标签架构 table
schema "posts" do
field :title, :string
field :body, :string
many_to_many :tags, App.Tag, join_through: App.PostsTags , on_replace: :delete
timestamps()
end?
如何使用 put_assoc 确保标签存在?
def changeset(struct, params \ %{}) do
struct
|> cast(params, [:title, :body])
|> put_assoc(:tags, parse_tags(params), required: true)
|> validate_required([:title, :body, :tags])
end
两者都需要:put_assoc 上的 true 和添加 :tags 以验证 required 并没有像我想象的那样工作。
validate_length/3
可用于检查 tags
列表是否为空:
Post 架构:
defmodule MyApp.Blog.Post do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Blog.Post
schema "blog_posts" do
field :body, :string
field :title, :string
many_to_many :tags, MyApp.Blog.Tag, join_through: "blog_posts_tags"
timestamps()
end
@doc false
def changeset(%Post{} = post, attrs) do
post
|> cast(attrs, [:title, :body])
|> put_assoc(:tags, attrs[:tags], required: true)
|> validate_required([:title, :body])
|> validate_length(:tags, min: 1)
end
end
标记架构:
defmodule MyApp.Blog.Tag do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Blog.Tag
schema "blog_tags" do
field :name, :string
timestamps()
end
@doc false
def changeset(%Tag{} = tag, attrs) do
tag
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
存在 tags
时验证成功:
iex(16)> Post.changeset(%Post{}, %{title: "Ecto Many-to-Many", body: "Lots of words", tags: [%{name: "tech"}]})
#Ecto.Changeset<action: nil,
changes: %{body: "Lots of words",
tags: [#Ecto.Changeset<action: :insert, changes: %{name: "tech"}, errors: [],
data: #MyApp.Blog.Tag<>, valid?: true>], title: "Ecto Many-to-Many"},
errors: [], data: #MyApp.Blog.Post<>, valid?: true>
当 tags
为空时产生错误:
iex(17)> Post.changeset(%Post{}, %{title: "Ecto Many-to-Many", body: "Lots of words", tags: []})
#Ecto.Changeset<action: nil,
changes: %{body: "Lots of words", tags: [], title: "Ecto Many-to-Many"},
errors: [tags: {"should have at least %{count} item(s)",
[count: 1, validation: :length, min: 1]}], data: #MyApp.Blog.Post<>,
valid?: false>
当 tags
为 nil 时产生错误:
iex(18)> Post.changeset(%Post{}, %{title: "Ecto Many-to-Many", body: "Lots of words"})
#Ecto.Changeset<action: nil,
changes: %{body: "Lots of words", title: "Ecto Many-to-Many"},
errors: [tags: {"is invalid", [type: {:array, :map}]}],
data: #MyApp.Blog.Post<>, valid?: false>