We begin with Posts

Building an app with Phoenix : part 4 of 9 published on Aug 10, 2015

Our Readdit app has one major ingredient. Posts! User’s need to be able to make posts so other users can read their amazing thoughts.

Create our Post Migration

We first need to make a database migration to add the posts table to our database.

We can generate a migration using mix and ecto with:

$ mix ecto.gen.migration create_posts
# /priv/repo/migrations/TIMESTAMP_create_posts.ex
defmodule Readdit.Repo.Migrations.CreatePosts do
  use Ecto.Migration

  def change do
    create table(:posts) do
      add :title, :string
      add :content, :text


After our migration file is created, we need to run our migration.

$ mix ecto.migrate
[info]  == Running Readdit.Repo.Migrations.CreatePosts.change/0 forward
[info]  create table posts
[info]  == Migrated in 0.1s

Create our Post Model

Next, we will create our Post Ecto model inside our /web/models folder.

# /web/models/post.ex
defmodule Readdit.Post do
  use Readdit.Web, :model
  import Ecto.Query

  schema "posts" do
    field :title, :string
    field :content, :string


There is no naming convetion being enforced with Ecto. The schema function accepts the table name as a parameter so you can connect any model with any table. This means you could have a model called GiantRobotChickens and connect to a table called ninja_monkeys. More realistically, you can create different models that act as views on the same table.

Inserting our first Post in the console

To open an interactive Elixir console with our Phoenix application loaded, we run:

iex -S mix

Based on the command, we are really loading our mix application. With Phoenix that just so happens to be our Phoenix application.

Now inside our interactive console, we have access to our Ecto models like Post.

Let’s insert our first Post.

> post = %Readdit.Post{title: "Hello World", content: "Welcome to Phoenix!"}

%Readdit.Post{__meta__: #Ecto.Schema.Metadata<:built>,
 content: "Welcome to Phoenix!", id: nil, inserted_at: nil,
 title: "Hello World", updated_at: nil}
> Readdit.Repo.insert!(post)

[debug] BEGIN [] OK query=57.4ms queue=2.5ms
[debug] INSERT INTO "posts" ("content", "inserted_at", "title", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" ["Welcome to Phoenix!", {{2015, 8, 24}, {1, 31, 46, 0}}, "Hello World", {{2015, 8, 24}, {1, 31, 46, 0}}] OK query=3.0ms
[debug] COMMIT [] OK query=0.6ms
%Readdit.Post{__meta__: #Ecto.Schema.Metadata<:loaded>,
 content: "Welcome to Phoenix!", id: 1,
 inserted_at: #Ecto.DateTime<2015-08-24T01:31:46Z>, title: "Hello World",
 updated_at: #Ecto.DateTime<2015-08-24T01:31:46Z>}

Retrieving Posts in the console

Let’s check that the record was inserted successfully by retrieving all the Posts from the database.

> Readdit.Repo.all(Readdit.Post)

[debug] SELECT p0."id", p0."title", p0."content", p0."inserted_at", p0."updated_at" FROM "posts" AS p0 [] OK query=76.1ms queue=3.6ms
[%Readdit.Post{__meta__: %Ecto.Schema.Metadata{source: {nil, "posts"},
   state: :loaded}, content: "Welcome to Phoenix!", id: 1,
  inserted_at: #Ecto.DateTime<2015-07-23T18:51:33Z>, title: "Hello World",
  updated_at: #Ecto.DateTime<2015-07-23T18:51:33Z>}]

Exiting the console

To exit iex just hit ctrl+C.

Next: Displaying Posts