bohdan-shulha
Using belongs_to in an embedded schema to create new records
Hi there.
I have another problem which I can’t fight on myself.
I have a deeply nested schema in my Ecto model. One of the deep inside branches looks like this:
embeds_many :configs, ConfigSpec, on_replace: :delete do
def changeset(config_spec, attrs) do
config_spec
|> cast(attrs, [:target])
|> cast_assoc(:config,
required: true,
with: &PtahServer.DockerConfigs.DockerConfig.changeset/2
)
|> validate_required([:target])
end
field :target, :string
belongs_to :config, PtahServer.DockerConfigs.DockerConfig
end
Everything works fine until I want to add a new ConfigSpec.
I have been using the hidden inputs approach with the :configs_sort field, but whenever I click “add an item” I’m getting non-loaded association error on the :config field.
It works perfectly fine if database already has some data (I preload everything what’s required), fails only for items being created at the moment.
** (ArgumentError) using inputs_for for association `config` from `PtahServer.Services.Service.ServiceSpec.TaskTemplate.ContainerSpec.ConfigSpec` but it was not loaded. Please preload your associations before using them in inputs_for
What will be the right approach here?
Form is really deeply nested. ![]()
stack[services][0][spec][task_template][container_spec][configs][0][config]
stack[services] is the list of Ecto models, whereas spec and everything inside (except the config field) are embedded schemas.
For the record, here is my PR: https://github.com/ptah-sh/ptah_server/pull/87
The related code belongs to lib/ptah_server_web/live/stack_live/components/service_component.html.heex
I have tried to manually override values in the changeset, but no luck - embedded records can be created, but the entity defined via belongs_to is not created.
First Post!
sodapopcan
You need to build an empty association for every new one you want. For example:
defmodule Bar do
schema "bars" do
belongs_to :foo, Foo
end
end
defmodule Foo do
schema "foos" do
has_many :bars, Bar
end
def append_empty_bar(changeset) do
new_bar = %Bar{}
current_bars = Ecto.Changeset.get_assoc(changeset, :bars) # in your case, `get_embed`
updated_bars = current_bars ++ [new_bar]
Ecto.Changeset.put_assoc(:bars, updated_bars) # or in your case, `put_embed`
end
end
# In some context function:
changeset =
Foo.changeset()
|> Foo.append_new_bar()
I wouldn’t necessarily call this exemplary code, I just wanted to make it as clear as I could (apologies if I failed here).
You should take a look at this lib: ecto_nested_changeset.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









