在 Ecto 中更新现有数据时,我应该使用变更集吗?
Shall I use changeset when update existing data in Ecto?
我在变更集管道中有加密令牌的功能。
def changeset(user, params \ %{}) do
user
|> cast(params, [:id, :token]
|> encrypt(:token)
end
由于这个功能是新的,旧数据还没有加密,我需要手动进行。然后我遇到了问题。
如果我将原始 token
传递给变更集,它会将值视为没有变化。管道中的 encrypt
不工作并且值不更新。
如果我加密 token
并传递给变更集,它会标记为更改,并应用 encrypt
函数。但是,它加密了 twice
.
一种笨拙的方法是在 encrypt
上添加检查以检查 token
是否加密。但是请记住,在我们将新令牌传递给变更集之前,我们仍然需要检查令牌是否已加密。也就是说,我们检查了两次。
所以我正在寻找一个简单的解决方案,如果有人有想法的话。
干杯
由于这是一个 运行-once 操作,我会进行迁移,直接在此处调用 Ecto.Repo.update/2
(unfortunately I did not find a way to call Ecto.Repo.update_all/3
,除非您可以直接在数据库中执行 encrypt
。)
defmodule My.Repo.Migrations.EncryptTokens do
@moduledoc false
use Ecto.Migration
def up do
for unencrypted <- from(...) |> Repo.all() do
unencrypted
|> Ecto.Changeset.change(token: encrypt(unencrypted.token))
|> Repo.update()
end
end
def down, do: raise "unrevertable"
end
旁注:你也可以看看Ecto.Changeset.force_change/3
fwiw。
我在变更集管道中有加密令牌的功能。
def changeset(user, params \ %{}) do
user
|> cast(params, [:id, :token]
|> encrypt(:token)
end
由于这个功能是新的,旧数据还没有加密,我需要手动进行。然后我遇到了问题。
如果我将原始 token
传递给变更集,它会将值视为没有变化。管道中的 encrypt
不工作并且值不更新。
如果我加密 token
并传递给变更集,它会标记为更改,并应用 encrypt
函数。但是,它加密了 twice
.
一种笨拙的方法是在 encrypt
上添加检查以检查 token
是否加密。但是请记住,在我们将新令牌传递给变更集之前,我们仍然需要检查令牌是否已加密。也就是说,我们检查了两次。
所以我正在寻找一个简单的解决方案,如果有人有想法的话。
干杯
由于这是一个 运行-once 操作,我会进行迁移,直接在此处调用 Ecto.Repo.update/2
(unfortunately I did not find a way to call Ecto.Repo.update_all/3
,除非您可以直接在数据库中执行 encrypt
。)
defmodule My.Repo.Migrations.EncryptTokens do
@moduledoc false
use Ecto.Migration
def up do
for unencrypted <- from(...) |> Repo.all() do
unencrypted
|> Ecto.Changeset.change(token: encrypt(unencrypted.token))
|> Repo.update()
end
end
def down, do: raise "unrevertable"
end
旁注:你也可以看看Ecto.Changeset.force_change/3
fwiw。