问题描述
我在 Users
和 Organizations
之间建立了多对多关系,使用自定义 Members
架构作为连接表。
简化模式:
schema "members" do
field :role,:string
field :organization_id,:id
field :user_id,:id
end
schema "organizations" do
field :name,:string
many_to_many :users,App.Users.User,join_through: App.Organizations.Members,join_defaults: [role: "read"]
end
schema "users" do
many_to_many :organizations,App.Organizations.Organization,join_defaults: [role: "read"]
end
问题:如何在创建新变更集时修改成员的 role
参数? IE。当我创建新用户(和组织)时,如何在此处传递 role
使其成为默认值以外的值?
user = User.changeset(%User{},%{"organizations": [%{"name": "test org"}]})
|> Ecto.Changeset.cast_assoc(:organizations,with: &App.Organizations.Organization.changeset/2)
解决方法
根据(the docs):
注意:通过关联是只读的。例如,您不能使用 Ecto.Changeset.cast_assoc/3 通过关联修改。
我通常用 Ecto.Multi
处理这些事情:
user_attrs = %{"name" => "Alice"}
organization_attrs = %{"name" => "The Club"}
member_attrs = %{"role" => "Manager"}
Ecto.Multi.new()
|> Ecto.Multi.insert(:user,User.changeset(%User{},user_attrs))
|> Ecto.Multi.insert(
:organization,Organization.changeset(%Organization{},organization_attrs)
)
|> Ecto.Multi.insert(
:member,fn %{user: %{id: user_id}},%{organization: %{id: organization_id}} ->
Member.changeset(
%Member{},Enum.into(member_attrs,%{"user_id" => user_id,"organization_id" => organization_id})
)
end
)
|> Repo.transaction()
|> case do
{:ok,%{user: user,organization: organization,member: member}} -> {:ok,user}
{:error,_,changeset,_} -> {:error,changeset}
end
我没有尝试编译该代码,因此可能需要调整。