The purpose of this article is sharing with other geeks my experience developing an application with Elixir. A few months ago I just did some researches in coding with Erlang and to be honest I really enjoyed it writing the article First steps with Erlang, but this time I will go for a more real application which could provide me with some better feedback about this functional programming language.

What’s Elixir?

Elixir is a dynamic, functional language designed for building scalable and maintainable applications and run over the Erlang Virtual Machine

What’s Ecto?

Ecto is a database wrapper that makes the life easier for Elixir developers who need to make use of database in their applications. Ecto works with Postgresql, Mysql, MSSQL, SQLite3 and MongoDB.

In this tutotial we will be working with a Postgresql but we could do de same with any of the above databases.

Creating the project

By this point I assume you all have elixir installed on your computer. If not, you only need to got to the Elixir Siteand follow the installation steps.

Create the project

  mix new -app <APP_NAME>


This will create some directories:

  • _build: This directory contains only compiled code and libraries.

  • config: Configuration for our application.

  • deps: Dependencies used by this application.

  • lib: The code of our project.

  • test: Unit testing for our application

  • mix.exs: In this file we define the dependencies and the application modules.

  • priv/repo: SQL scripts and Elixir migration scripts.

Adding dependencies

Since we are working with Postgresql we need to add the driver beside of the Ecto dependency.

So in the mix.exs file we add the below

  def application do
    [applications: [:logger, :postgrex, :ecto]]
  defp deps do
    {:postgrex, ">= 0.0.0"},
    {:ecto, "~> 2.0.0"}

and to downlaod dependcy we run the command

  mix deps.get

Configuring our database connection

First af all we create a Repo for our application. We create a new file in directory lib,


 defmodule ElixirEctoTraining.Repo do
   use Ecto.Repo,
   otp_app: :elixir_ecto_training

and then we edit file /config/config.exs to define the database driver connection. For this tutorial we assume a postgresql instance run on port 3001 (we can make use of docker-compose.yml in docker directory)

  config :elixir_ecto_training, ecto_repos: [ElixirEctoTraining.Repo]
  config :elixir_ecto_training, ElixirEctoTraining.Repo,
    adapter: Ecto.Adapters.Postgres,
    database: "elixir_ecto_training_db",
    username: "wesovi",
    password: "wesoviPass",
    hostname: "localhost",
    port: "3001"

Ecto tasks

Ecto provides with samo taks which we can find running

   mix ecto --help


Creating the database by running ecto.create


Defining the tables structure.

We need to create a file called /priv/lib/structure.sql. So far we will only create a table to store tracks.

CREATE SEQUENCE tracks_id_seq;
  id bigint NOT NULL DEFAULT nextval('tracks_id_seq'),
  title   VARCHAR,
  inserted_at timestamp without time zone
ALTER SEQUENCE tracks_id_seq OWNED BY tracks.id;

To create the tables we only need to run command ecto.load


We can check the table has been created by using any Postgresql Admin Tool,

Oooops… we forgot defining a column singer in table tracks… What can we do now?, We well generate a new migration for do this.


We need to edit new migration file in order to write our sql change.

defmodule ElixirEctoTraining.Repo.Migrations.AddColumnSingerToTableTracks do
  use Ecto.Migration

  def change do
    alter table(:tracks) do
        add :singer, :string

We can have a look at all the migrations and theis statuses by running mix ecto.migration


To make the change defined in the migration file we can do by mix ecto.migrate -v 20160717214057


And the new column singer has been added to the table tracks.

Mapping tables to elixir structures

We create a new file /lib/model.exs and define a new module as below:

defmodule ElixirEctoTraining.Track do
  use Ecto.Schema
  import Ecto.Query

  schema "tracks" do
    field :title
    field :singer
    field :inserted_at


Testing the application

We modify mix.exs file and add the below content

def application do
      applications: [:logger, :postgrex, :ecto],
      mod: {ElixirEctoTraining,[]}

In order to run our tests agains a empty database we will create an aliases in out mix.exs file

What’s an aliases Aliases allow us to perform some tasks that contain sub-tasks

  def project do
      [app: :elixir_ecto_training,
       version: "0.1.0",
       elixir: "~> 1.3",
       build_embedded: Mix.env == :prod,
       start_permanent: Mix.env == :prod,
       deps: deps(),
       aliases: aliases]

  defp aliases do
        "ecto.rebuild": [
            "ecto.drop", "ecto.create",  "ecto.load", "ecto.migrate", "test"
        "test": [

We can write a very basic test. The purpose of this test is check tha following: We have an empty table tracks and add a new record then we have 1 record.

So we create a file /test/elixir_ecto_training.ex and with the below content

defmodule ElixirEctoTrainingTest do
  alias ElixirEctoTraining.Track
  alias ElixirEctoTraining.Repo
  import Ecto.Query

  use ExUnit.Case, async: true

  setup do
    :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo)
    Ecto.Adapters.SQL.Sandbox.mode(Repo, {:shared, self()})

  test "track insertion" do
    previousNumberOfTracks = List.first Repo.all(from u in Track, select: count(u.id))
    Repo.insert! %Track{ title: "Runaway", singer: "John Bon Jovi" }
    numberOfTracks = List.first Repo.all(from u in Track, select: count(u.id))
    assert numberOfTracks == previousNumberOfTracks + 1


To run the tests we do

      mix test


The code

As always the code can be found on wesovilabs repository