上一篇我們寫出了新增跟修改資料庫記錄功能,當然不會想要每次用的時候都打這麼多行,通常會把一系列的邏輯整理好放在相對應的 context 裡面。
在 Phoenix 的 context 其實就一個普通的 elixir 模組,預設跟 schema 的擺設方式可以參照之前用產生器產生的 Note 模組
├── lib
│ ├── blog
│ │ ├── notes.ex
│ │ ├── notes
│ │ │ └── note.ex
我們也在 lib/blog/ 底下建立一個 posts.ex 檔
defmodule Blog.Posts do
# 這兩行是待會寫 Query 要用到的模組
import Ecto.Query, warn: false
alias Blog.Repo
# 在這邊 alias 在這個 context 常常會用到的 schema
alias Blog.Posts.Post
end
把我們昨天寫好的貼上來整理成方法吧!
defmodule Blog.Posts do
import Ecto.Query, warn: false
alias Blog.Repo
alias Blog.Posts.Post
def create_post(attrs \\ %{}) do
%Post{}
|> Post.changeset(attrs)
|> Repo.insert()
end
def update_post(%Post{} = post, attrs) do
post
|> Post.changeset(attrs)
|> Repo.update()
end
end
定義方法的時候如果在變數後面加上
\\
就可以在後面加上該變數的預設值,像上面的create_post
因為 attrs 有預設值,所以create_post
雖然規格上是要收一個變數(create_post/1
) 但是他可以不帶變數使用預設值。
現在有了新增跟修改,我們再加一下讀取跟刪除吧
在預設的情況讀寫有兩種,一個是用特定 post 的 id 來把他的資料找出來,另一個是列出目前所有的 posts。
當然實際實作的時候只需要寫有用到的就好了。
以下方法直接放在 Post module 內
# 取得特定 post
def get_post(id) do
Repo.get(Post, id)
end
# 列出全部 posts
def list_posts() do
Repo.all(Post)
end
# 刪除傳入的 post
def delete_post(%Post{} = post) do
Repo.delete(post)
end
恭喜各位,已經成了 CRUD (寫入讀取更新刪除) 四大動作。
我們實際在 iex -S mix
裡面使用看看吧
# 在 iex -S mix 裡進行
alias Blog.Posts # alias Posts 出來讓他可以直接呼叫
# 新增並存到 post 變數裡,這邊要小心回傳的時候是 {:ok, post}, 要用 pattern matching 來接他
{:ok, post} =
Posts.create_post(%{
title: "新劇推薦",
body: "我不小心看到早上"
})
# 列出來看看剛剛新增的有沒有在裡面
Posts.list_posts()
# 覺得寫的文章很瞎把他刪掉
Posts.delete_post(post)