Shorthand for custom transformations (on_success)
The previous section was about transformations that come for free with Ecto.Schema
. Others are performed by other code.
Consider the code used on previous pages, which looks roughly like this:
The problem with that code is that casting an incorrect ISO8601 string will produce a changeset with:
an error value, but
no change associated with the
date
field.
As a result, the incorrect form field will be wiped out (set to blank). That's not much of a problem, given that you're probably using a date-picker on the front end (that only allows valid strings) and if someone's circumventing the web page to generate bad POST values, well, they deserve what they get. Nevertheless, let's replace it with a schema like this:
Here, the date_string
can be anything. It's not up to the cast
to translate the string into a Date
; it's the responsibility of another part of the changeset
function, something like the last line below:
This pair of fields is like the as_cast
values on the previous page in that the result is easily predictable from the input. On the previous page, :date
was the result of Changeset.cast
. Here, it's the result of Date.from_iso8601
applied to the :date_string
field. In both cases, the result is a trivial function call...
... at least in the non-error case. Let's focus on the success case here because, as is often the case, the result is calculated by a function we don't have to write. (We'll look at the error case later.)
Here is how to indicate date
's transformation:
Notice that the on_success
argument looks like a function call. Any is_atom
argument is taken to refer to other values in the changeset.
Given this field_transformation
, we don't have to write a changeset
check for date
. That is, this:
... will automatically check that the value of date
is ~D[2001-01-01]
.
If you don't like that on_success
notation (which uses a macro), you can use a function form:
That form is required if you're using an anonymous function rather than one from a module:
Both forms can take more than one argument. Here, for example, are the two ways of describing the result of a days_since_2000
field that's calculated from date
:
Note that the non-atom value is taken as-is; it's not used for a changeset lookup like :date
is.
Last updated
Was this helpful?