再做過修改之後,其實新增的流程非常類似,熟練後也可以一次把需要的 new 與 create 方法在 controller 建立起來
# 有新增表格的 new 方法
def new(conn, _params) do
# 用 空的 Post struct 建立新的 changeset
changeset = Posts.change_post(%Posts.Post{})
# 顯示 :new 畫面 (`new.html.heex`),一樣傳 changeset 準備給表格
render(conn, :new, changeset: changeset)
end
# 用 create 方法接收表格送出,收 params 的方式一樣
def create(conn, %{"post" => post_params}) do
# 建立表格
case Posts.create_post(post_params) do
# 如果成功的話,跳轉到該篇新文章的 show 頁面
{:ok, post} ->
redirect(conn, to: Routes.post_path(conn, :show, post))
# 失敗的話重新 render :new 頁面
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :new, changeset: changeset)
end
end
邏輯相當類似,甚至連 template 也非常類似
唯一不同的地方只有 form 的 action ,這次是指到 create
<h1>新增文章</h1>
<.form let={f} for={@changeset} action={Routes.post_path(@conn, :create)}>
<%= label(f, :title) %>
<%= text_input(f, :title) %>
<%= error_tag(f, :title) %>
<%= label(f, :body) %>
<%= textarea(f, :body) %>
<%= error_tag(f, :body) %>
<div>
<%= submit("送出") %>
</div>
</.form>
普通使用者不太可能知道 /posts
後面加上 /new
就可以到新增
我們可以加在 index 頁面上面,編輯按鈕也一起
<h1>顯示 post 的 index 頁面</h1>
<%= link("新增文章", to: Routes.post_path(@conn, :new), class: "button") %>
<%= for post <- @posts do %>
<article>
<h2><%= post.title %></h2>
<p><%= post.body %></p>
<div>
<%= link("編輯", to: Routes.post_path(@conn, :edit, post)) %>
<%= link("閱讀更多", to: Routes.post_path(@conn, :show, post)) %>
</div>
</article>
<% end %>