Raphael Rafatpanah
Raphael Rafatpanah

Reputation: 19967

Create nested associations

Please consider the following schema:

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

This answer shows how one can put two associations on a struct.

I've followed that pattern and it works nicely.

def create_conversation(%{business: business, contact: contact, message: message} = attrs) do
  business
  |> Ecto.build_assoc(:conversations)
  |> Ecto.Changeset.change()
  |> Ecto.Changeset.put_assoc(:contact, contact)
  |> Repo.insert()
end

However, I'm wondering what the idiomatic way would be to also create a message (which is an association of the newly created conversation above) so that it would be associated with this newly created conversation. Does it make sense to do this in one Repo.insert() call or not? How would someone experienced in Elixir / Ecto approach this problem?

Upvotes: 0

Views: 549

Answers (1)

Raphael Rafatpanah
Raphael Rafatpanah

Reputation: 19967

Wow, this works!

def create_conversation(%{business: business, contact: contact, message: message} = attrs) do
  business
  |> Ecto.build_assoc(:conversations)
  |> Ecto.Changeset.change()
  |> Ecto.Changeset.put_assoc(:contact, contact)
  |> Ecto.Changeset.put_assoc(:messages, [%Message{body: message.body}])
  |> Repo.insert()
end

Upvotes: 1

Related Questions