I have a transactions table where a row of transaction can be split (although not my use case: you can think of a bill being split amongst friends). Initially I considered all splits to be stored in a separate table but we will be capturing the exact same information except the amount will be different and they add some extra description field.
schema "transactions" do
field :date, :date
field :amount, :float
field :has_splits, :boolean, default: false
field :temp_id, :string, virtual: true
field :delete, :boolean, virtual: true
belongs_to :parent_transaction, Transactions, source: :parent_transaction_id
has_many :children_transactions, Transactions, references: :parent_transaction_id
end
When I try to save this changeset:
#Ecto.Changeset<
action: nil,
changes: %{
children_transactions: [
#Ecto.Changeset<
action: :insert,
changes: %{
amount: 149.0,
date: ~D[2021-10-21],
parent_transaction_id: "0b57d9b7-5459-4caa-bdc0-1031893f5ae7",
},
errors: [],
data: #App.Transaction.Transactions<>,
valid?: true
>,
#Ecto.Changeset<
action: :insert,
changes: %{
amount: 100.0,
date: ~D[2021-10-21],
parent_transaction_id: "0b57d9b7-5459-4caa-bdc0-1031893f5ae7",
},
errors: [],
data: #App.Transaction.Transactions<>,
valid?: true
>
]
},
errors: [],
data: #App.Transaction.Transactions<>,
valid?: true
>
I get this odd error:
[error] GenServer #PID<0.748.0> terminating
** (ArgumentError) unknown field `:transactions_parent_transaction_id` in %App.Transaction.Transactions{__meta__: #Ecto.Schema.Metadata<:built, "transactions">, amount: nil, children_transactions: #Ecto.Association.NotLoaded<association :children_transactions is not loaded>, date: nil, delete: nil, has_splits: false, id: nil, inserted_at: nil,parent_transaction: #Ecto.Association.NotLoaded<association :parent_transaction is not loaded>, parent_transaction_id: nil, temp_id: "b4d90993-f845-42e6-9f13-55e524b5d3e1", updated_at: nil}
(ecto 3.7.1) lib/ecto/changeset.ex:1234: Ecto.Changeset.put_change/7
(ecto 3.7.1) lib/ecto/changeset.ex:1213: Ecto.Changeset.put_change/3
(ecto 3.7.1) lib/ecto/association.ex:811: Ecto.Association.Has.on_repo_change/5
(ecto 3.7.1) lib/ecto/association.ex:572: anonymous fn/8 in Ecto.Association.on_repo_change/7
(elixir 1.13.2) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto 3.7.1) lib/ecto/association.ex:568: Ecto.Association.on_repo_change/7
(elixir 1.13.2) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto 3.7.1) lib/ecto/association.ex:532: Ecto.Association.on_repo_change/4
(ecto 3.7.1) lib/ecto/repo/schema.ex:905: Ecto.Repo.Schema.process_children/5
(ecto 3.7.1) lib/ecto/repo/schema.ex:985: anonymous fn/3 in Ecto.Repo.Schema.wrap_in_transaction/6
(ecto_sql 3.7.1) lib/ecto/adapters/sql.ex:1021: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4
(db_connection 2.4.1) lib/db_connection.ex:1531: DBConnection.run_transaction/4
(app 0.1.0) lib/app/live/transactions_live/split_transaction_component.ex:88: AppWeb.TransactionsLive.SplitTransactionComponent.handle_event/3
(phoenix_live_view 0.17.6) lib/phoenix_live_view/channel.ex:566: anonymous fn/4 in Phoenix.LiveView.Channel.inner_component_handle_event/4
(telemetry 0.4.3) /Users/dev/elixir/deps/telemetry/src/telemetry.erl:272: :telemetry.span/3
(phoenix_live_view 0.17.6) lib/phoenix_live_view/diff.ex:206: Phoenix.LiveView.Diff.write_component/4
(phoenix_live_view 0.17.6) lib/phoenix_live_view/channel.ex:490: Phoenix.LiveView.Channel.component_handle_event/6
(stdlib 3.17) gen_server.erl:695: :gen_server.try_dispatch/4
(stdlib 3.17) gen_server.erl:771: :gen_server.handle_msg/6
(stdlib 3.17) proc_lib.erl:236: :proc_lib.wake_up/3
What’s the right away to model self-referential tables?
Thanks!