So I have this changeset:
def changeset(object, params) do
object
|> cast(params, [:attr1, :attr2])
|> put_assoc(:assoc, params[:assoc])
|> validate_required([:attr1, :attr2, :assoc])
end
It works very well when I create the object because assoc
already exists, hence I call something like:
Object.changeset(object, %{attr1: "value", attr2: "value", assoc: %Assoc{with_data: true}})
But then I need to update attr2
only. I would expect to use the same:
Object.changeset(object, %{attr2: "new Value"})
But it fails because it tries to put_assoc(nil)
. So I need to write
def put_assoc_if_present(changeset, nil), do: changeset
def put_assoc_if_present(changeset, assoc), do: put_assoc(changeset, assoc)
def changeset(object, params) do
object
|> cast(params, [:attr1, :attr2])
|> put_assoc_if_present(:assoc, params[:assoc])
|> validate_required([:attr1, :attr2, :assoc])
end
Or |> put_assoc(:assoc, params[:assoc] || object.assoc)
It feels lame. I’m guessing this is not the elixir way of doing this, but on the other hand, cast
is really fine with all attributes not being here, why shouldn’t put_assoc
, cast_assoc
, put_embed
and cast_embed
?
I mean the point of a changeset is to register all changes, but no change is very fine, it shouldn’t fail then, should it?
Thanks for your insights