iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0
Modern Web

速成 Phoenix, 2022年最受喜愛框架系列 第 9

{09, Phoenix, "從 schema 開始 (下)"}

  • 分享至 

  • xImage
  •  

建立 schema 表格建立對應的欄位

剛開始用 generator 建立一份完整的基本新增修改流程還有一個方便的地方,就是自己實作或是修改的時候可以產生一個來參考最標準簡單寫法,就是忘記可以去抄啦!

參考 Blog.Notes.Note schema blog/lib/blog/notes/note.ex 來做一份給 posts 吧

資料庫上的資料型態跟 Elixir 在 schema 使用的型態有得時候會不一樣
可以參考 Ecto 文件裡的 Types and casting
像是 :varchar, :text, :string 在 schema 都用 :string 就可以了

# blog/lib/blog/posts/post.ex
defmodule Blog.Posts.Post do
  use Ecto.Schema

  schema "posts" do
    field(:title, :string)
    field(:body, :string)

    timestamps()
  end
end

有了 schema 後我們要撈取資料就會比較方便

# iex -S mix
Blog.Repo.all(Blog.Posts.Post)

看起來有點醜嗎,可以先把要用的模組 alias 起來

alias Blog.Repo
alias Blog.Posts.Post

Post
|> Repo.all()

小技巧,在 iex 如果要使用 |> 的話,因為換行就會執行該行的結果,看要打成同一行

"foo" |> String.slice(1, 2)

或是在還沒結束那行的後面加上 \

"foo" \
|> String.slice(1, 2)

為 schema 加上 changeset 用的驗證

下一篇會解釋 Ecto 與他怎麼使用 changeset 來新增更改資料,但再那之前我們可以先把這張表想要的驗證寫出來
我們在下面加一個叫 changeset 的方法,(對,一樣抄 notes 的就可以了,但是要記得改欄位名稱)

defmodule Blog.Posts.Post do
  use Ecto.Schema
  import Ecto.Changeset # 記得 import Changeset 模組

  schema "posts" do
    field(:title, :string)
    field(:body, :string)

    timestamps()
  end

  def changeset(note, attrs) do
    note
    |> cast(attrs, [:title, :body])
    |> validate_required([:title, :body])
  end
end

這個 changeset 通常每個 schema 都要有一個,我們之後新增修改或是驗證資料是否合格的時候都會自動呼叫這個方法。
這個 changeset 收兩個變數,第一個是正在更改的主角,在這邊的話可能代表一個 Post
%Post{title: "文章B", body: "文章B的內容", ..後略}
第二個變數是 params,是這次要更改的輸入,通常是表格填入的內容,詳細結構我們後面會解釋,這邊先大概的知道在幹嘛就可以了

  1. 我們用 cast 把 attrs 帶入 changeset 裡面,後面的 list 是我們允許帶入的列表
  2. 用 validate_required 來做必填檢查,後面是要檢查的欄位,如果我把 :body 從裡面拿掉,我的 body 欄位就可以選填

等等這個是誰 %Post{} ,我知道 %{} 是 Map
這個是 struct ,簡單解釋就是有規範的 Map
如果我使用 這個 struct 沒有規定的 key,就會錯誤


上一篇
{08, Phoenix, "從 schema 開始 (上)"}
下一篇
{10, Ecto, "Changeset 改變集"}
系列文
速成 Phoenix, 2022年最受喜愛框架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言