Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 嵌套儿童的外祖父母钥匙_Elixir_Phoenix Framework_Ecto - Fatal编程技术网

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
选项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])
  )