elixir - 使用 Ecto 将项目添加到多对多关联
问题描述
我有一个与“用户”关联的“板”模块。
我想简单地将用户添加到“用户”关联中。
schema "boards" do
# ...
many_to_many :users, User, join_through: "boards_users"
timestamps()
end
现在在我的代码中,我刚刚插入了一条新记录,并且我有一个“板”实例。
我想将“用户”与此板相关联,但目前我必须执行以下操作。
有没有更简单的方法来做到这一点?似乎分配了代码来简单地将用户附加/关联到“板”模块上的“用户”集合。
- 我必须重新加载“板”实例以预加载所有用户
- 我追加用户
- 我必须调用 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
解决方案
如果您不跳过连接表,而是用另一种模式覆盖它,那真的很容易:
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 通过正确定义的外键执行。
推荐阅读
- angular - 我的完整日历工具提示没有结果
- css - 为什么我不能为自定义属性(又名 CSS 变量)设置动画?
- java - 未找到列表视图
- testing - JMeter HTTP 请求失败
- url - 使用 SSO 用户/通行证卷曲
- javascript - 如何从 Reactjs 中的 input\textArea 获取“中断”?
- node.js - 如何使异步等待对调用数据库的函数起作用
- java - Javax.Persistence.Tuple,如何模拟数据
- android - 当我将带有颜色的样式放在头部时,Webview 什么也不显示
- css - 引导容器 - 由于绝对定位,包含宽度超过 100% 的 div