Lesson 4

Building an Index Action

In this lesson we will build a page to list out all the quotes in our application. We will use the QuoteController and index action.

In advance we know we will build full CRUD functionality on the QuoteController, so we can setup the full set of RESTful, resourceful, routes all at once.

To do this, edit web/router.ex and add the following line:

defmodule Splurty.Router do
  use Phoenix.Router

  pipeline :browser do
    plug :accepts, ~w(html)
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
  end

  pipeline :api do
    plug :accepts, ~w(json)
  end

  scope "/", Splurty do
    pipe_through :browser # Use the default browser stack

    get "/", QuoteController, :homepage
resources "/quotes", QuoteController
end # Other scopes may use custom stacks. # scope "/api", Splurty do # pipe_through :api # end end

Save the file.

Whenever I change the routes file, I like to verify that my code changes did what I expected, so I will run the command to display the routes table:

$ mix phoenix.routes

Right now it will say:

quote_path  GET     /                 Splurty.QuoteController.homepage/2
quote_path  GET     /quotes           Splurty.QuoteController.index/2
quote_path  GET     /quotes/:id/edit  Splurty.QuoteController.edit/2
quote_path  GET     /quotes/new       Splurty.QuoteController.new/2
quote_path  GET     /quotes/:id       Splurty.QuoteController.show/2
quote_path  POST    /quotes           Splurty.QuoteController.create/2
quote_path  PATCH   /quotes/:id       Splurty.QuoteController.update/2
            PUT     /quotes/:id       Splurty.QuoteController.update/2
quote_path  DELETE  /quotes/:id       Splurty.QuoteController.destroy/2

The single-line code change hooked up the full set of RESTful routes on our QuoteController.

Restart your server.

Navigate in your web browser to the URL that looks like: localhost:4000/quotes. You should see an error message explaining there is an undefined function: Splurty.QuoteController.index/2.

This indicates we must add an index action to the QuoteController. Edit web/controllers/quote_controller.ex and add it:

defmodule Splurty.QuoteController do
  use Phoenix.Controller

  plug :action

  def homepage(conn, _params) do
    render conn, "homepage.html"
  end

def index(conn, _params) do render conn, "index.html" end
end

Save the file and refresh the page. It will show you an error message that indicates the template index.html hasn't been created. This means we must create one.

Create a file web/templates/quote/index.html.eex that contains the following text:

YOLO!

Save the file and refresh the page. Awesome, we no longer see an error message, instead we see the text from our template file.

We want this page to list out each of the quotes in our database, but right now our database has no quotes in it. Let's jump into iex and add a couple quotes in our database so this page has data it can display. To start with spin up iex by running the following command:

$ iex -S mix

Store two quotes into the database, by running commands like this:

> quote = %Splurty.Quote{saying: "They hate us, cause they ain't us.", author: "Dave Skylark"}
> Repo.insert(quote)
> quote2 = %Splurty.Quote{saying: "They're peanut butter and jealous.", author: "Dave Skylark"}
> Repo.insert(quote2)

Then press CTRL+C twice to exit iex.

Since we now have two quotes in our database our goal will be to list all of the quotes in our database on the index template.

The first step is to load the quotes in our controller, and allow our template access the records. Edit the index action in web/controller/quote_controller.ex so the code looks like this:

defmodule Splurty.QuoteController do
  use Phoenix.Controller

  plug :action

  def homepage(conn, _params) do
    render conn, "homepage.html"
  end

def index(conn, _params) do conn |> assign(:quotes, Repo.all(Splurty.Quote)) |> render("index.html") end
end

This will render the index.html.eex template and give the template access to @quotes, which will be a list of all the quotes that exist in our database.

Edit web/templates/quote/index.html.eex and replace it's contents with this, so it displays a table on the page, with a table row for each record in our database:

<table>
  <thead>
    <tr>
      <th>Saying</th>
      <th>Author</th>
  </thead>
  <%= for q <- @quotes do %>
  <tr>
    <td>
      <%= q.saying %>
    </td>
    <td>
      <%= q.author %>
    </td>
  </tr>
  <% end %>

</table>

Save the file and open localhost:4000/quotes in your browser.

Your application should look just like this at this step.

Next Lesson