为多对多转换关联变更集
Cast association changeset for many to many
我在用户和设施之间有这样的多对多关系:
schema "facilities" do
field(:name, :string)
field(:description, :string)
many_to_many(:users, User, join_through: "users_facilities")
end
schema "users" do
field(:first_name, :string)
field(:last_name, :string)
field(:email_address, :string)
field(:username, :string)
many_to_many(:facilities, Facility, join_through: "users_facilities")
end
这是changeset_params
:
%{
name: john,
users: [%{id: 1286, name: "john doe"}, %{id: 1287, name: "jane doe"}]
}
它适用于 has_many
并且给我整个关联的单个变更集。但不适用于 many to many
.
records_struct
设施齐全,关联加载用户
这是代码:
Facility.changeset(records_struct, changeset_params)
|> Ecto.Changeset.cast_assoc(:users)
我收到从 Facility.changeset 返回的变更集,但是 Ecto.Changeset.cast_assoc
在我尝试测试它时抛出 internal server
错误。
您的用户和设施是独立管理的。换句话说,您不会在用户的变更集中创建新设施,反之亦然。您只想 bind/associate 到已经存在的实体,对吗?
对于这种情况,您需要 Ecto.Changeset.put_assoc/4
请记住,在执行 put_assoc
之前,您需要预加载关联。
还要确保在 many_to_many
关联中设置 on_replace 选项,例如:
many_to_many(:users, User, join_through: "users_facilities", on_replace: :delete)
对于多对多关联,您很可能需要 :delete
。
这意味着当您在变更集中传递关联记录时,它将删除与之前关联但不在当前变更集中的记录的关联。它不会删除关联的记录。
我在用户和设施之间有这样的多对多关系:
schema "facilities" do
field(:name, :string)
field(:description, :string)
many_to_many(:users, User, join_through: "users_facilities")
end
schema "users" do
field(:first_name, :string)
field(:last_name, :string)
field(:email_address, :string)
field(:username, :string)
many_to_many(:facilities, Facility, join_through: "users_facilities")
end
这是changeset_params
:
%{
name: john,
users: [%{id: 1286, name: "john doe"}, %{id: 1287, name: "jane doe"}]
}
它适用于 has_many
并且给我整个关联的单个变更集。但不适用于 many to many
.
records_struct
设施齐全,关联加载用户
这是代码:
Facility.changeset(records_struct, changeset_params)
|> Ecto.Changeset.cast_assoc(:users)
我收到从 Facility.changeset 返回的变更集,但是 Ecto.Changeset.cast_assoc
在我尝试测试它时抛出 internal server
错误。
您的用户和设施是独立管理的。换句话说,您不会在用户的变更集中创建新设施,反之亦然。您只想 bind/associate 到已经存在的实体,对吗?
对于这种情况,您需要 Ecto.Changeset.put_assoc/4
请记住,在执行 put_assoc
之前,您需要预加载关联。
还要确保在 many_to_many
关联中设置 on_replace 选项,例如:
many_to_many(:users, User, join_through: "users_facilities", on_replace: :delete)
对于多对多关联,您很可能需要 :delete
。
这意味着当您在变更集中传递关联记录时,它将删除与之前关联但不在当前变更集中的记录的关联。它不会删除关联的记录。