在 Elixir 中,put_assoc 应该如何使用?

问题描述 投票:0回答:1

对于一个项目,我需要在 Elxir、Phoenix 创建一个小应用程序,使用 Ecto 作为 ORM。

我是这项技术的初学者,我在多对多关联上遇到了节省问题。

这是关于团队<->用户关系,其中用户可以拥有多个团队,团队可以包含多个用户。目前,数据库和对象看起来不错。

这是我的架构:

团队架构

 schema "teams" do
    field :description, :string
    field :title, :string
    field :date_creation, :naive_datetime
    belongs_to :manager, BackEndService.Users.User
    many_to_many :users, BackEndService.Users.User, join_through: "users_teams"

    timestamps(type: :utc_datetime)
  end

用户架构

  schema "users" do
    field :username, :string
    field :email, :string
    field :hash_password, :string
    field :grade, :integer
    has_many :clocks, BackEndService.Clocks.Clock
    many_to_many :teams, BackEndService.Teams.Team, join_through: "users_teams"

    timestamps(type: :utc_datetime)
  end

真正的问题是当我尝试将用户添加到如下团队时:

    首先我从列表中获取用户:
  1. def get_users(ids) do users_from_list_query = from u in User, where: u.id in ^ids Repo.all(users_from_list_query) |> Repo.preload([:teams]) end

  2. 然后我尝试将他们插入一个团队:
  3. users_to_inject = Users.get_users(attrs.users_ids) team = get_team!(attrs.team_id) team |> Repo.preload([:users, :manager]) |> Ecto.Changeset.change |> Ecto.Changeset.put_assoc(:users, [users_to_inject]) |> Repo.update!

  4. 这会导致以下错误:
  5. ** (ArgumentError) invalid changes being applied to changeset. Expected a keyword list or a map, got: [%BackEndService.Users.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 2, username: "Sec User", email: "[email protected]", hash_password: "$pbkdf2-sha512$160000$jUnAuyThExRqhgSfqCzT.Q$H4ReypEz5DDfqBcTqANbWe0t2Z0hOTM5.YXU2EJCvyV2PViVIPSmPEXPpaNRwhUxaRh59cQ1NwCP4SqBHSA9yQ", grade: 20, clocks: [], teams: [%BackEndService.Teams.Team{__meta__: #Ecto.Schema.Metadata<:loaded, "teams">, id: 1, description: "Rapide descriptiumlorem ipsum", title: "Équipe N1", date_creation: ~N[2023-10-25 15:05:34], manager_id: 1, manager: #Ecto.Association.NotLoaded<association :manager is not loaded>, users: #Ecto.Association.NotLoaded<association :users is not loaded>, inserted_at: ~U[2023-10-27 13:11:48Z], updated_at: ~U[2023-10-27 13:11:48Z]}, %BackEndService.Teams.Team{__meta__: #Ecto.Schema.Metadata<:loaded, "teams">, id: 2, description: "Rapide descriptiumlorem ipsum", title: "Équipe N2", date_creation: ~N[2023-10-25 15:05:34], manager_id: 1, manager: #Ecto.Association.NotLoaded<association :manager is not loaded>, users: #Ecto.Association.NotLoaded<association :users is not loaded>, inserted_at: ~U[2023-10-27 14:09:37Z], updated_at: ~U[2023-10-27 14:09:37Z]}], inserted_at: ~U[2023-10-26 14:38:32Z], updated_at: ~U[2023-10-26 14:38:32Z]}]
有什么我错过的吗?

P.S:这是我在平台上的第一个问题,所以请毫不犹豫地提供更好的问题编辑提示

[编辑]:即使当 users_to_inject 仅包含一个条目时,问题仍然是相同的

database error-handling elixir many-to-many ecto
1个回答
1
投票

正如@Yatender Singh 在评论中提到的,我正在“包装”一些“不需要它”的东西。事实上,从
    Repo.all()
  1. 检索的信息已经采用了良好的格式。 我的模式
    users_teams
    关系上
  2. 缺少属性
  3. :on_replace 必须根据我的需要进行设置(此处删除所有以前的数据以替换为新的数据)。给出以下行many_to_many :users, BackEndService.Users.User, join_through: "users_teams", on_replace: :delete
    最后我用 
    |> Repo.update!
    而不是
    |> Repo.update()
  4. 更新数据
© www.soinside.com 2019 - 2024. All rights reserved.