【发布时间】:2016-09-16 06:04:39
【问题描述】:
我正在开发一个多用户、多房间聊天应用程序,我的模型如下(为简单起见,省略了 App 模型):
defmodule Elemental.TxChat.User do
use Elemental.TxChat.Web, :model
schema "users" do
# The rooms the user is currenly logged into
many_to_many :rooms, Elemental.TxChat.Room, join_through: "rooms_users"
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [])
|> validate_required([])
end
end
和
defmodule Elemental.TxChat.Room do
use Elemental.TxChat.Web, :model
schema "rooms" do
field :name, :string
# The user id that created this room
field :created_by, :integer
field :created_from_app, :integer
many_to_many :members, Elemental.TxChat.User, join_through: "rooms_users"
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name, :created_from_app, :created_by])
|> validate_required([:name, :created_by, :created_from_app])
end
end
接下来,我从iex 创建了一些房间和用户(每个三个)。现在我想知道:假设我希望 user1 属于 room1 和 room2,并且 user2 属于 room2 和 room3 ......怎么办?
在我看来,虽然定义模式很好,但必须有一个中间步骤来执行类似user1.rooms = [room1, room2] 的操作。所以我最终访问了this post,并看到了build_assoc 的示例:
Ecto.build_assoc(current_user, :post)
所以这个应用程序有用户和帖子,并试图链接它们。但我不明白它是如何实现的。数据库/Ecto 如何知道哪个用户 id 与哪个帖子 id 链接?
无论如何,我尝试在我的应用程序的iex 中执行此操作:
iex(46)> Ecto.build_assoc(user1, :rooms, room1)
%Elemental.TxChat.Room{__meta__: #Ecto.Schema.Metadata<:built, "rooms">,
created_by: 1, created_from_app: 1, id: 2,
inserted_at: #Ecto.DateTime<2016-09-16 05:00:00>,
members: #Ecto.Association.NotLoaded<association :members is not loaded>,
name: "room1", updated_at: #Ecto.DateTime<2016-09-16 05:00:00>}
我认为函数调用会将user1 加入模型Room,使用room1 中的数据来查找目标房间。当我在输出中看到<association :members is not loaded> 时,我的心沉了下去,但我想我应该检查一下数据库。你猜怎么着,我的加入表(rooms_users)中没有条目。 :(
我认为很明显需要以某种方式创建模型之间的这些链接,但我似乎碰壁了。如何做到这一点?
【问题讨论】:
标签: elixir phoenix-framework ecto