What are constraints?

Now that we’ve taken a look at validations, let’s look at the other tool Ecto provides to ensure that data is correct.

On the surface, constraints work a lot like validations. They can be piped along with validations when building a changeset, and they check specific aspects of a changeset to ensure that the underlying data is correct. Unlike validations, constraints are enforced by the database, not by Elixir code.


For example, let’s consider the genres table we worked with in the last chapter. We want to be sure that each of the genre records has a unique name. For example, say we want to ensure we won’t have two records called “jazz.” One approach would be to enforce this in our Elixir code. We could check the database for a duplicate record before we try to insert a new one. That would work most of the time, but there’s always the possibility of a race condition. Another process could insert the duplicate record between the time we looked for it and when we inserted our new record.

We can only be sure that we won’t introduce duplicate records if we add a unique index in the database itself. In this case, we’d want to add an index to the name column of the genre database table. We’ll look at exactly how to do this later.

With that index in place, we can be sure that the database will prevent the creation of duplicate records. If we attempt to do so, the database will block it and Ecto will raise an error.

We’ll try to insert a Genre record for “speed polka” twice in this example. The first call will succeed, but the second will fail, as shown below.

Get hands-on with 1200+ tech skills courses.