首页 > 解决方案 > 使用 Ecto 将项目添加到多对多关联

问题描述

我有一个与“用户”关联的“板”模块。

我想简单地将用户添加到“用户”关联中。

 schema "boards" do
    # ...

    many_to_many :users, User, join_through: "boards_users"

    timestamps()
  end

现在在我的代码中,我刚刚插入了一条新记录,并且我有一个“板”实例。

我想将“用户”与此板相关联,但目前我必须执行以下操作。

有没有更简单的方法来做到这一点?似乎分配了代码来简单地将用户附加/关联到“板”模块上的“用户”集合。

  1. 我必须重新加载“板”实例以预加载所有用户
  2. 我追加用户
  3. 我必须调用 change,然后 put_assoc,然后调用 update

这是我必须做的还是我以非常冗长的方式做这件事?

当我只是将另一个用户附加到集合时,我想避免加载所有用户,这可能吗?

board = Repo.get(__MODULE__, id) |> Repo.preload(:users)

board_users = board.users ++ [user] 
                  |> Enum.map(&Ecto.Changeset.change/1)

board
|> Ecto.Changeset.change
|> Ecto.Changeset.put_assoc(:users, board_users)
|> Repo.update

标签: elixirphoenix-frameworkecto

解决方案


如果您不跳过连接表,而是用另一种模式覆盖它,那真的很容易:

schema "boards_users" do
  belongs_to :user, User
  belongs_to :board, Board
end

然后,请求将如下所示:

%BoardUser{user: u, board: b}
|> Repo.insert()

使用这种方法,您甚至可以单独处理对数据库的单个请求

%BoardUser{user_id: user_id, board_id: id)
|> Repo.insert()

在这里,您不应该点击数据库来获取板,而所有验证都可以由 DB 通过正确定义的外键执行。


推荐阅读