为多对多转换关联变更集

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。 这意味着当您在变更集中传递关联记录时,它将删除与之前关联但不在当前变更集中的记录的关联。它不会删除关联的记录。