How do you set up an Ecto changeset to prevent models missing required fields from being saved?
<p>According to the Phoenix documentation:</p>

<blockquote>
  <p>insert(Ecto.Schema.t | Ecto.Changeset.t, Keyword.t) ::   {:ok,
  Ecto.Schema.t} |   {:error, Ecto.Changeset.t}</p>
  
  <p>Inserts a model or a changeset.</p>
  
  <p>In case a model is given, the model is converted into a changeset with
  all model non-virtual fields as part of the changeset. This conversion
  is done by calling Ecto.Changeset.change/2 directly.</p>
  
  <p>In case a changeset is given, the changes in the changeset are merged
  with the model fields, and all of them are sent to the database.</p>
  
  <p>If any before_insert or after_insert callback is registered in the
  given model, they will be invoked with the changeset.</p>
  
  <p>It returns {:ok, model} if the model has been successfully inserted or
  {:error, changeset} if there was a validation or a known constraint
  error.</p>
</blockquote>

<h2>What I did</h2>

<pre><code>defmodule Dollar.User do
    use Dollar.Web, :model

    schema "users" do
        field :username, :string
        field :sms_number, :string
        field :email, :string

        timestamps
    end

    @required_fields ~w(sms_number)
    @optional_fields ~w(username email)

    @doc """
    Creates a changeset based on the `model` and `params`.
    If no params are provided, an invalid changeset is returned
    with no validation performed.
    """
    def changeset(user, params \\ :empty) do
        user
        |&gt; cast(params, @required_fields, @optional_fields)
        |&gt; validate_length(:sms_number, is: 10)
        |&gt; unique_constraint(:sms_number)
        |&gt; unique_constraint(:username)
    end
end
</code></pre>

<h2>What I expected</h2>

<pre><code>Repo.insert(%User{})
=&gt; {:error, ... }
</code></pre>

<p>I expected an error because the <code>sms_number</code> is <strong>required</strong>.</p>

<h2>What I actually got</h2>

<pre class="lang-sh prettyprint-override"><code>[debug] INSERT INTO "users" ("inserted_at", "updated_at", "email", "sms_number", "username") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [{{2016, 3, 19}, {15, 13, 5, 0}}, {{2016, 3, 19}, {15, 13, 5, 0}}, nil, nil, nil] OK query=1.5ms
%Dollar.User{__meta__: #Ecto.Schema.Metadata&lt;:loaded&gt;, email: nil, id: 7,
 inserted_at: #Ecto.DateTime&lt;2016-03-19T15:13:05Z&gt;, sms_number: nil,
 updated_at: #Ecto.DateTime&lt;2016-03-19T15:13:05Z&gt;, username: nil}
</code></pre>

<p>The record is stored in the database</p>

<h2>Environment</h2>

<ul>
<li>Elixir 1.2.3</li>
<li>Ecto 1.1.4</li>
<li>Phoenix Ecto 2.0.1</li>
<li>Phoenix 1.1.4</li>
</ul>

<p>What am I doing wrong?</p>