Better way to add value into existing assoc with put_assoc

I have a self referencing User model with clients and owners set as many_to_many.

I’m trying to create a new user and make that user as the owner of an existing user, who already has previous owners (not replacing the existing owners but to add this new one).
The following does exactly that, but it looks kind of bad. Would there be a better or cleaner way to do this?

  def create_owner_client(owner_to) when is_integer(owner_to) do
    owner = create_user() |> Repo.preload([:clients, :owners])

    client = Repo.get_by(User, id: owner_to) |> Repo.preload([:clients, :owners])

    client
    |> Ecto.Changeset.change
    |> Ecto.Changeset.put_assoc(:owners, [owner | client.owners])
    |> Repo.update!
    
    owner
    |> Ecto.Changeset.change
    |> Ecto.Changeset.put_assoc(:clients, [client])
    |> Repo.update!
  end

What bothers me here is that client = Repo.get… bit. I though I could do something like this:

client = Repo.get_by(User, id: owner_to)
|> Repo.preload([:clients, :owners])
|> Ecto.Changeset.change
|> Ecto.Changeset.put_assoc(:owners, [owner | client.owners])
|> Repo.update!

But it seems like I can’t (client.owners is not recognised). So basically I’m missing something like ‘this’ to refer to the client.owners.

You’d have to do Ecto.Changeset.put_assoc(...) in another function:

``` def put_owner_client(client, owner) do Ecto.Changeset.put_assoc(client, :owners, [owner | client.owners]) end ``` Then use it like this: ``` client = Repo.get_by(User, id: owner_to) |> Repo.preload([:clients, :owners]) |> Ecto.Changeset.change() |> put_owner_client(owner) |> Repo.update!() ```

Thanks, I tried it but now I’m getting an error saying
** (KeyError) key :owners not found in: ecto.Changeset<action: nil, changes: %{}, errors: [] …

Sorry, try to see if this works:

def put_owner_client(%Ecto.Changeset{data: client} = changeset, owner) do
  Ecto.Changeset.put_assoc(changeset, :owners, [owner | client.owners])
end

It works, outstanding!

Thank you very much sir