gpt4 book ai didi

elixir - Phoenix 框架和验证嵌入

转载 作者:行者123 更新时间:2023-12-01 02:40:42 24 4
gpt4 key购买 nike

鉴于以下代码工作正常:

image_1 = %Image{naturalHeight: "100", naturalWidth: 100}

diffbot_objects = [
%DiffbotObject{
availability: true,
images: [
image_1
]
}
]

changeset = Ecto.Changeset.change(product)
changeset = Ecto.Changeset.put_embed(changeset, :diffbot_objects, diffbot_objects)

如何确保在 Image 模型上验证字段?我可以使用 Image 模型上的 changeset 方法生成变更集(见下文),但我无法使用嵌套变更集插入数据,它似乎必须是 e struct 。

我的图像模型:
defmodule Shopshare.Product.DiffbotObject.Image do
use Shopshare.Web, :model

embedded_schema do
field :naturalHeight, :integer
field :naturalWidth, :integer
end

@required_fields ~w(naturalHeight, naturalWidth)
@optional_fields ~w()

def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end

最佳答案

我看到你正在使用 put_embed但我没有看到产品的架构。我不知道这是否是真正的问题。但我尝试了一些有效的代码。

我使用博客和帖子模型创建了一个新应用程序。我使用了生成模型:

mix phoenix.gen.model Blog blogs name:string
mix phoenix.gen.model Post posts title:string body:text blog_id:references:blogs

我正在对必填字段使用简单的验证。让我们更深入地研究一下博客模型:
    defmodule MyApp.Blog do
use MyApp.Web, :model

schema "blogs" do
field :name, :string
has_many :posts, MyApp.Post

timestamps
end

@required_fields ~w(name)
@optional_fields ~w()

def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end

我手动创建 has_many与帖子的关联(它不是用我的生成模型创建的)。现在,我们有了 Post 模型:
    defmodule MyApp.Post do
use MyApp.Web, :model

schema "posts" do
field :title, :string
field :body, :string
belongs_to :blog, MyApp.Blog

timestamps
end

@required_fields ~w(title body)
@optional_fields ~w()

def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end

现在,我们可以在 IEx ( iex -S mix ) 中播放:
    iex(1)> blog_changeset = MyApp.Blog.changeset(%MyApp.Blog{}, %{name: "blog name"})
%Ecto.Changeset{...}

iex(2)> blog_changeset.valid?
true

iex(3)> invalid_post_changeset = MyApp.Post.changeset(%MyApp.Post{}, %{})
%Ecto.Changeset{...}

iex(4)> blog_changeset = Ecto.Changeset.put_assoc(blog_changeset, :posts, [invalid_post_changeset])
%Ecto.Changeset{action: nil,
changes: %{name: "blog name",
posts: [%Ecto.Changeset{action: :insert,
changes: ..., constraints: [],
errors: [title: "can't be blank", body: "can't be blank"], filters: %{},
...]}, ...,
model: %MyApp.Blog{...}, optional: [], opts: [], params: %{"name" => "blog name"},
prepare: [], repo: nil, required: [:name],
types: %{...},
valid?: false, validations: []}

iex(5)> blog_changeset.valid?
false

我抑制了一些输出以专注于错误。 Changeset像一棵树一样工作。因此,您可以拥有父变更集和子变更集。与您的代码的不同之处在于我使用的是 put_assoc ( https://hexdocs.pm/ecto/Ecto.Changeset.html#put_assoc/4 )(也许关系也是如此,但我没有看到您的架构)。

来自 put_assoc 的预期行为:

If the association has no changes, it will be skipped. If the association is invalid, the changeset will be marked as invalid. If the given value is not an association, it will raise.



我希望这可以帮助你。

关于elixir - Phoenix 框架和验证嵌入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34897957/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com