Adding new routes in Phoenix

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0

This is another part of my series on learning Elixir.

Last week I mixed new Phoenix project and looked how different parts of framework fit together. This week I started adding my own routes and pages. I followed the official guide but altered it a bit to better fit my application.

Adding a Route
First things to change, when you’re adding new pages, is the router.ex file, that sits in the web folder in your project. All of the work today will be contained within web folder. To add a new route, simply add a new line within the existing scope. We’ll talk more about scopes in one of the future episodes.

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

    get "/", PageController, :index
    get "/flights", FlightsController, :index
  end

What the new Route says is, when browser hits /flights path, index action of FlightsController controller will be executed. Or in other words, this routes maps GET request for /flights to the index action of FlightsConroller. This won’t work because this controller doesn’t exist yet. Let’s fix it!

Adding a Controller
The Controller is very similar to the one I created last week. Nothing new here. We have index function that renders index.html view.

defmodule Flightlog.FlightsController do
  use Flightlog.Web, :controller

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


Adding a View and a Template
As you can see below, I added some code to the Template. I’m quite sure that it should be handled in View, but for now, I hard coded it this way. Below flights_view.ex and index.html.eex:

defmodule Flightlog.FlightsView do
  use Flightlog.Web, :view
end

You can also see reference to the path /flights/1 that has not been declared. Let’s do it now.

Adding another Route, Controller and Template
I pasted below the code for all three files, marking changes in bold.

defmodule Flightlog.Router do
  use Flightlog.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

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

    get "/", PageController, :index
    get "/flights", FlightsController, :index
    get "/flights/:id", FlightsController, :show
  end

  # Other scopes may use custom stacks.
  # scope "/api", Flightlog do
  #   pipe_through :api
  # end
end
defmodule Flightlog.FlightsController do
  use Flightlog.Web, :controller

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

  def show(conn, %{"id" => id}) do
    render conn, "show.html", id: id
  end
end

There were no changes in flights_view.ex.

There are some important things happening here. In Router, I pattern match against the params passed into the show function so that the id variable is bound to the value we put in the :id position in the URL. For example, if our URL is http://localhost:4000/flights/1, the id variable would be bound to 1.

In Template, I again hard coded some logic. There are for sure better ways to do it, but it works for now. It’s worth mentioning, that id passed is a string! I debugged this for an hour while comparing to integer 1 and couldn’t figure out why it doesn’t work ;). Everyday you learn something new. And the effects:

http://localhost:4000/flights/1

Screen Shot 2017-03-21 at 23.51.09.png

http://localhost:4000/flights/2

Screen Shot 2017-03-21 at 23.51.29.png

As you can see it’s all rendered within parent template. I’m not gonna get bothered by this at this point.

If you want to read more about Templates, again official guide is fantastic. I also stumbled upon this very interesting blog post that explains that Templates are just functions.

Thanks for reading this another part of my adventures with Elixir and Phoenix. Come next week for more. And if you’re interested in machine learning, look into my weekly link drop. on that topic.

Advertisements

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0