Hello. I’m working with existing code and need to modify a changeset on a schema in order to work for my use case. I need to modify the required fields, however I don’t want to insert in the other two fields that are required in addition to the one I need (I only need to update one variable (e.g. var 2 on the struct and not var1 and var0).
What is the best way to do this? Other code relies on this changeset.
def changeset(struct, params) do
required_params = [:var0, :var1, :var2]
struct
|> cast(params, required_params)
|> validate_required(required_params)
|> validate_length(:var0, is: 10)
|> validate_var1()
end
From my research, I came to the conclusion that change instead of cast may be a better option, but I’d like to know if that is the best option and what are the pros / cons.
Comments on best practices are very appreciated as I am new to this language.
Ecto.Changeset.change/2 is used for internal/trusted data; it doesn’t perform filtering, casting and validation.
Ecto.Changeset.cast/4 is used for external/untrusted data, most commonly data coming from user input.
You are of course not limited to a single changeset function in your Schema; also a changeset function can call other reusable changesets. For example:
def changeset(user, attrs) do
user
|> cast(attrs, [:name, :username])
|> validate_required([:name, :username])
|> validate_length(:username, min: 1, max: 20)
end
def registration_changeset(user, params) do
user
|> changeset(params)
|> cast(params, [:password])
|> validate_required([:password])
|> validate_length(:password, min: 6, max: 100)
|> put_pass_hash()
end