我有一个包含子文档嵌入列表的文档。如何使用Ecto更新/更改嵌入列表中的某个特定文档?
defmodule MyApp.Thing do
use MyApp.Model
schema "things" do
embeds_many :users, User
end
end
defmodule MyApp.User do
use MyApp.Model
embedded_schema do
field :name, :string
field :email, :string
field :admin, :boolean, default: false
end
end
defmodule MyApp.Model do
defmacro __using__(_) do
quote do
use MyApp.Web, :model
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id # For associations
end
end
end
答案 0 :(得分:0)
到目前为止,我的解决方案是生成除了我要更新的用户之外的所有用户的列表,并创建一个用户的变更集和其他用户的新列表,然后在该事物上put_embed
此列表。它有效,但感觉必须有一个更优雅的解决方案。
user = Enum.find(thing.users, fn user -> user.id == user_id end)
other_users = Enum.filter(thing.users, fn user -> user.id != user_id end)
user_cs = User.changeset(user, %{email: email})
users = [user_cs | other_users]
thing
|> Ecto.Changeset.change
|> Ecto.Changeset.put_embed(:users, users)
|> Repo.update
编辑:我刚刚发现了这个“解决方案”的严重陷阱。未受影响的用户也会更新,这可能是同意呼叫(竞争条件)的问题。所以必须有另一种解决方案。