I’m following Programming Phoenix 1.4 book.
In the rumbl
app right at the start when we have to list all the users in the index.html
template, we need the following two routes even if we are rendering only the index page.
get "/users", UserController, :index
get "/users/:id", UserController, :show
If we remove the second route, a request to localhost:4000/users
fails. Why is so?
Why only the first route isn’t enough in that case?
If you want to reproduce this, follow the following,
- Run,
mix phx.new rumbl
cd rumbl
mix ecto.create
-
remove everything below first first
section
tag fromtemplates/page/index.html.eex
-
create
lib/rumbl/accounts/user.ex
with the following content
defmodule Rumbl.Accounts.User do
defstruct [:id, :name, :username]
end
- And
lib/rumbl/accounts.ex
with content,
defmodule Rumbl.Accounts do
alias Rumbl.Accounts.User
def list_users() do
[
%User{id: "1", name: "Jose", username: "josevalim"},
%User{id: "2", name: "Bruce", username: "redrapids"},
%User{id: "3", name: "Chris", username: "chrismccord"}
]
end
def get_user(id) do
Enum.find(list_users(), fn map -> map.id == id end)
end
def get_user_by(params) do
Enum.find(list_users(), fn map ->
Enum.all?(params, fn {key, val} -> Map.get(map, key) == val end)
end)
end
end
- Add this route to the
router.ex
get "/users", UserController, :index
# notice that we're not adding the get "/users/:id" route
- Add
user_controller.ex
as,
defmodule RumblWeb.UserController do
use RumblWeb, :controller
alias Rumbl.Accounts
def index(conn, _params) do
users = Accounts.list_users()
render conn, "index.html", users: users
end
end
- And
user_view.ex
as,
defmodule RumblWeb.UserView do
use RumblWeb, :view
alias Rumbl.Accounts.User
def first_name(%User{name: name}) do
name
|> String.split(" ")
|> Enum.at(0)
end
end
- And finally the template
lilb/rumbl_web/templates/user/index.html.eex
,
<h1>Listing Users</h1>
<table>
<%= for user <- @users do %>
<tr>
<td><b><%= first_name user %></b> (<%= user.id %>)</td>
<td><%= link "View", to: Routes.user_path(@conn, :show, user.id) %></td>
</tr>
<% end %>
</table>
**Now when you run mix phx.server
and access localhost:4000/users
it will give you an error that you don’t have the :show
route.
What is the point of adding the show route if the cycle is already complete?