为具有嵌套关联的深层嵌套结构创建 Ecto 变更集
Create Ecto changeset for deeply nested struct with nested associations
请考虑以下架构:
schema "businesses" do
...
has_many :contacts, Contact
has_many :conversations, Conversation
...
end
schema "contacts" do
...
belongs_to :business, Business
has_one :conversation, Conversation
...
end
schema "conversations" do
...
belongs_to :business, Business
belongs_to :contact, Contact
has_many :messages, Message
...
end
schema "messages" do
belongs_to :conversation, Conversation
belongs_to :contact, Contact
end
鉴于我有一个 business
结构,我将如何以处理关联的方式创建 contact
、conversation
和 message
结构?
以下在排除 messages
部分时有效。
business
|> Ecto.build_assoc(
:contacts,
%Contact{name: name, phone: phone}
)
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(
:conversation,
%Conversation{business: business}
|> Ecto.Changeset.change()
|> Ecto.Changeset.cast_assoc(:business)
)
# |> Ecto.Changeset.put_assoc(:messages, [%Message{body: "hello"}])
|> Repo.insert()
倒数第二行未注释,PostgreSQL 让我知道 message
应该有一个 conversation_id
,这是真的。怎么设置?
添加一个 IO.inspect()
:
business
|> Ecto.build_assoc(
:contacts,
%Contact{name: name, phone: phone}
)
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(
:conversation,
%Conversation{business: business}
|> Ecto.Changeset.change()
|> Ecto.Changeset.cast_assoc(:business)
)
|> IO.inspect()
# |> Ecto.Changeset.put_assoc(:messages, [%Message{body: "hello"}])
|> Repo.insert()
表明我们在尝试设置 messages
关联之前正在使用以下变更集:
#Ecto.Changeset<
action: nil,
changes: %{
conversation: #Ecto.Changeset<action: :insert, changes: %{}, errors: [],
data: #Conversation<>, valid?: true>
},
errors: [],
data: #Contact<>,
valid?: true
有没有办法让新创建的message
与同时新创建的contact
和新创建的conversation
相关联?
这可以通过 Ecto.Multi
实现。
请考虑以下架构:
schema "businesses" do
...
has_many :contacts, Contact
has_many :conversations, Conversation
...
end
schema "contacts" do
...
belongs_to :business, Business
has_one :conversation, Conversation
...
end
schema "conversations" do
...
belongs_to :business, Business
belongs_to :contact, Contact
has_many :messages, Message
...
end
schema "messages" do
belongs_to :conversation, Conversation
belongs_to :contact, Contact
end
鉴于我有一个 business
结构,我将如何以处理关联的方式创建 contact
、conversation
和 message
结构?
以下在排除 messages
部分时有效。
business
|> Ecto.build_assoc(
:contacts,
%Contact{name: name, phone: phone}
)
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(
:conversation,
%Conversation{business: business}
|> Ecto.Changeset.change()
|> Ecto.Changeset.cast_assoc(:business)
)
# |> Ecto.Changeset.put_assoc(:messages, [%Message{body: "hello"}])
|> Repo.insert()
倒数第二行未注释,PostgreSQL 让我知道 message
应该有一个 conversation_id
,这是真的。怎么设置?
添加一个 IO.inspect()
:
business
|> Ecto.build_assoc(
:contacts,
%Contact{name: name, phone: phone}
)
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(
:conversation,
%Conversation{business: business}
|> Ecto.Changeset.change()
|> Ecto.Changeset.cast_assoc(:business)
)
|> IO.inspect()
# |> Ecto.Changeset.put_assoc(:messages, [%Message{body: "hello"}])
|> Repo.insert()
表明我们在尝试设置 messages
关联之前正在使用以下变更集:
#Ecto.Changeset<
action: nil,
changes: %{
conversation: #Ecto.Changeset<action: :insert, changes: %{}, errors: [],
data: #Conversation<>, valid?: true>
},
errors: [],
data: #Contact<>,
valid?: true
有没有办法让新创建的message
与同时新创建的contact
和新创建的conversation
相关联?
这可以通过 Ecto.Multi
实现。