Editing a Post

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

Edit Post Route

The edit route is similar to the show route because we specify an :id in our route and we register a name for the route.

# /web/router.ex
scope "/", Readdit do
  ...
  get "/posts", PostsController, :index
  get "/posts/new", PostsController, :new
  post "/posts", PostsController, :create
  get "/posts/:id", PostsController, :show, as: :post
  get "/posts/:id/edit", PostsController, :edit, as: :post
  ...
end

Edit Post Controller Endpoint

Our controller’s endpoint will find the Post to edit by the id and pass it to our view.

# /web/controllers/posts_controller.ex
defmodule Readdit.PostsController do
  ...
  def edit(conn, %{ "id" => id }) do
    post = Readdit.Post |> Readdit.Repo.get(id)
    render conn, "edit.html", post: post
  end
  ...
end

Edit Post Template

We will tell the form in our template to use the route returned by using our named post_path and to use the method PUT on form submission.

<!-- /web/templates/posts/edit.html.eex -->

<%= form_for @conn, post_path(@conn, :update, @post), [name: :post, method: :put], fn form -> %>
  <div class="form-group">
    <%= label(form, :title, "Title") %>
    <%= text_input(form, :title, value: @post.title, class: "form-control") %>
  </div>
  <div class="form-group">
    <%= label(form, :content, "Content") %>
    <%= textarea(form, :content, value: @post.content, class: "form-control") %>
  </div>
  <%= submit "Save", class: "btn btn-primary" %>
<% end %>

Add the Edit link

Back on our show page for Post we will add an edit link to go to our new edit page.

<!-- /web/templates/posts/show.html.eex -->
<h1><%= @post.title %></h1>

<%= link to: post_path(@conn, :edit, @post) do %>
 Edit
<% end %>

<p>
  <%= @post.content %>
</p>

Update Post Route

We now need to add our update route to the router.

# /web/router.ex
scope "/", Readdit do
  ...
  get "/posts", PostsController, :index
  get "/posts/new", PostsController, :new
  post "/posts", PostsController, :create
  get "/posts/:id", PostsController, :show, as: :post
  get "/posts/:id/edit", PostsController, :edit, as: :post
  put "/posts/:id", PostsController, :update, as: :post
  ...
end

Update Post Controller Endpoint

# /web/controllers/posts_controller.ex
defmodule Readdit.PostsController do
  ...
  def update(conn, %{ "id" => id, "post" => %{ "title" => title, "content" => content } }) do
    post = Readdit.Post |> Readdit.Repo.get(id)
    %{
      post |
      title: title,
      content: content
    } |> Readdit.Repo.update!

    conn |> redirect(to: post_path(conn, :show, post))
  end
  ...
end

Time to update a post

All done.

  1. Let’s go to http://localhost:4000/posts.
  2. From there we can click a post’s link and view its page.
  3. Clicking the Edit link will send up to the Post’s edit page.
  4. Change it’s title and/or contents and hit save.
  5. The Post should be updated and we should be redirected to the /posts page.
Next: Deleting a Post