Disclaimer: I'm a one-day-old Elixir/Phoenix developer.
In Sonny's training yesterday, we used an Ecto.Changeset to handle user registration (a database-backed operation). This worked perfectly for rendering the intial form and re-rendering the form with validation errors.
This is because our Workshop.RegistrationController is calling Repo.Insert which sets the changeset's :action, whether or not the insertion succeeds. Then Phoenix.HTML's form_for function appropriately sets errors on the form so they can be rendered on the page.