Elixir 嵌套儿童的外祖父母钥匙
一个Elixir 嵌套儿童的外祖父母钥匙,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,一个组织有许多用户 schema "organizations" do field :name, :string has_many :users, TestApp.User end 一个用户有许多下属 schema "users" do field :name, :string belongs_to :organization, TestApp.Organization belongs_to :manager, TestApp.User, foreign_key:
组织
有许多用户
schema "organizations" do
field :name, :string
has_many :users, TestApp.User
end
一个用户
有许多下属
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
以以下方式创建下属时,我如何确保下属具有组织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
选项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
选项2subordinate =
%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])
)