Slight twist on the usual nested associations question here:
I have two models (in this simple example, in reality, it’s dozens and dozens). Part
and PartManufacturer
.
The schema for Part
looks like this:
schema "parts" do
field :model, :string
belongs_to :manufacturer, PartManufacturer
end
The schema for PartManufacturer
looks like this:
schema "part_manufacturers" do
field :name, :string
end
The changes for inserting a new Part
looks like this:
def changeset(part, attrs) do
part
|> cast(attrs, [:model])
|> cast_assoc(:manufacturer)
end
Which works exactly as expected when using a Phoenix nested form (or other any other input method).
I would like to keep PartManufacturer
tidy, with a unique constraint on it’s name
field, which I’ve added in it’s changeset and on the DB table.
It works as expected, in that it prevents duplicate rows being inserted, throwing a changes error.
However, I’d like to use that pre-existing record within the Part
as it’s association, rather than throwing an error. Would I be right in saying that I need to approach it similarly to the ensure_author_exists
function from this part of the Phoenix guide: https://hexdocs.pm/phoenix/contexts.html#cross-context-data
In my case, that would involve pulling the manufacturer
map from the params, passing it through a similar function, and then mapping it back into the Part
attrs before using assoc_constraint
in the changes as opposed to cast_assoc
. Is that correct?
I’m scratching my head on this one, as I can’t get the right behaviour, and a bit nervous that I’ve bitten off more than I can chew. The end goal is a Bike
struct (and form) that has associations for each of it’s varying parts Brake
, Fork
etc, which in turn has associations to BrakeType
, BrakeManufacturer
etc. I’d like to be able to prompt users with auto-suggestions based on existing values, but also add new ones when using the form with nested associations. It’s certainly going to be fiddly!
Cheers,
Jamie.