Hi, I’ve been scratching my head around this for a while and trying different combinations, but I’m just stuck whilst using build_assoc
which does not recognise binary id UUIDs in my code. Here’s my problem and question.
I’m working on a banking app, so I have a user
and wallet
. user
was created with Pow
if that makes any difference. There is a has_many
relationship between user
and wallet
. Here are the schemas:
use MyApp.Schema
schema "users" do
field :role, :string, null: false, default: "user"
has_many :wallets, MyApp.Accounts.Wallet
pow_user_fields()
timestamps()
end
and
use MyApp.Schema
...
schema "wallets" do
field :description, :string
field :balance, Money.Ecto.Composite.Type
belongs_to :user_id, MyApp.Users.User, references: :uuid, type: :binary_id
timestamps()
end
where MyApp.Schema
is set up for UUIDs:
defmodule MyApp.Schema do
defmacro __using__(_) do
quote do
use Ecto.Schema
@primary_key {:uuid, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
@derive {Phoenix.Param, key: :uuid}
@timestamps_opts
end
end
end
Then in my CreateWallet
migration:
defmodule MyApp.Repo.Migrations.CreateWallets do
use Ecto.Migration
def change do
create table(:wallets) do
add :description, :string, null: false
add :balance, :money_with_currency, null: false
add :user_id, references(:users, column: :uuid, type: :binary_id, on_delete: :nothing)
timestamps()
end
create index(:wallets, [:user_id])
end
end
All standard I think so far. However, if I want to implement a create_user_wallet
function:
def create_user_wallet(%User{} = user, %{} = wallet_params) do
wallet = Ecto.build_assoc(user, :wallets, wallet_params)
Repo.insert(wallet)
end
and then try to run it, there is an error:
** (KeyError) key :user_uuid not found
(ecto 3.7.1) lib/ecto/association.ex:754: Ecto.Association.Has.build/3
This is fine if it’s referring to the uuid key in the user
map, as I don’t see user_uuid
there, it’s just %User{uuid: "1234..."}
- or is it referring to user_id
in the wallet
database? However, why should the build_assoc
function expect that and not function as is given the Schema
implementation and how can I override it, or set up my schemas and/or own Schema implementation and/or migration correctly?
Thanks for reading this far!