organization
有很多users
schema "organizations" do
field :name, :string
has_many :users, TestApp.User
end
user
有许多subordinates
schema "users" do
field :name, :string
belongs_to :organization, TestApp.Organization
belongs_to :manager, TestApp.User,
foreign_key: :manager_id
has_many :subordinates, TestApp.User,
foreign_key: :manager_id
end
如何以下列方式创建下属时,如何确保下属具有organization_id
值?
test "create Org and User and Subordinate in one step" do
subordinate =
%User{}
|> User.changeset(%{name: "A Subordinate"})
manager =
%User{}
|> User.changeset(%{name: "A Manager"})
|> Changeset.put_assoc(:subordinates, [subordinate])
organization =
%Organization{}
|> Organization.changeset(%{name: "An Organization"})
|> Changeset.put_assoc(:users, [manager])
%{users: [ %{subordinates: [subordinate]} = manager]} = organization = Repo.insert!(organization)
# Passes
assert manager.organization_id == organization.id
# Fails
assert subordinate.organization_id == organization.id
end
答案 0 :(得分:0)
<强>选项1 强>
调用Repo.insert!分别在每个变更集上
subordinate =
%User{}
|> User.changeset(%{name: "A Subordinate"})
|> Repo.insert!
manager =
%User{}
|> User.changeset(%{name: "A Manager"})
|> Changeset.put_assoc(:subordinates, [subordinate])
|> Repo.insert!
创建辅助函数,返回与其下属合并的管理者列表
defp managers_with_subordinates(managers) do
Enum.reduce(managers, [], &(&2 ++ [&1] ++ &1.subordinates))
end
然后将结果传递给put_assoc
users = managers_with_subordinates([manager])
organization =
%Organization{}
|> Organization.changeset(%{name: "An Organization"})
|> Changeset.put_assoc(:users, users)
并将模式匹配更改为
%{users: [user1, user2]} = organization = %Organization{} |> Organization.changeset |> put_assoc(:users, x) |> Repo.insert!
assert user1.organization_id == organization.id
assert user2.organization_id == organization.id
assert user2.manager_id == user1.id
<强>选项2 强>
subordinate =
%User{}
|> User.changeset(%{name: "A Subordinate"})
|> prepare_changes( fn(changeset) ->
manager = changeset.repo.get(User, changeset.changes.manager_id)
changeset |> cast(%{organization_id: manager.organization_id}, [:organization_id])
)