gpt4 book ai didi

Elixir Ecto 仅在创建时添加计算值

转载 作者:行者123 更新时间:2023-12-03 21:35:55 24 4
gpt4 key购买 nike

在创建/插入时添加计算值的最佳实践方法是什么?我应该为创建和更新创建一个唯一的变更集吗?

例如,我有一个博客文章模型,我想创建一个标题 slug 值并存储它。这有点做作,但出于某种原因我只想将其设置为创建而不是更新。我应该做类似下面的事情吗?

defmodule MyBlog.Post do
use MyBlog.Web, :model

schema "posts" do
field :title, :string
field :title_slug, :string
field :content, :text

timestamps
end

@required_fields ~w(
title
content
)

@optional_fields ~w()

def create_changeset(model, params \\ :empty) do
changeset(model, params)
|> generate_title_slug
end

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

defp generate_title_slug(changeset) do
put_change(changeset, :title_slug, __some_slug_generation_code__)
end

def update_changeset(model, params \\ :empty) do
changeset(model, params)
end
end

最佳答案

我强烈反对回调 - 它们难以测试、引入全局状态、晦涩难懂且难以推理。这也违背了 Elixir 的核心原则之一:“显式优于隐式”。

Ecto 的核心团队甚至正在考虑取消回调,或者更改名称并减少它们的暴露程度。在别无他法时,使用回调应该是最后的选择。

为了展示回调的问题之一,让我们想象一下您确实使用回调来解决此问题的场景。现在您正在设计一个管理界面,您不想在其中出现这种行为。你如何解决这个问题?你开始陷入禁用回调的困境,在异常中引入异常,并且有一个难以遵循的多分支条件逻辑。但这是一起解决了一个错误的问题!

对于 Ecto 的架构,不同的变更集方法非常好并且非常自然。这样您就可以对不同的操作进行不同的验证,并且没有什么是全局的。让我们想想您将如何解决我之前展示的场景中的问题。这非常简单 - 您创建另一个变更集函数!

我见过几次的解决方案是更改 changeset 函数以采用三个参数并在第一个参数的类型上进行模式匹配,例如:

def changeset(action, model, params \\ :empty)

def changeset(:create, model, params)
# return create changeset
end

def changeset(:update, model, params)
# return update changeset
end

我不确定哪个更好 - 多个函数或一个函数中的模式匹配。这主要是偏好问题。

关于Elixir Ecto 仅在创建时添加计算值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33906315/

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