上一章,我們已經建立好一個 Book 的 Model,以及 books 的 table,那接下來就開始實作 CRUD 吧!
當我們在終端機輸入$ rails console
或 $ rails c
,會進入到 Rails 的控制台中。
但不建議在這邊直接對資料庫進行操作,所以我們會使用 Rails 的沙盒模式進行操作,在終端機輸入:
$ rails c --sandbox
這樣就會進入沙盒模式了,第二行有寫「你在這邊的操作當離開時,將不會存進資料庫」,在這個模式你可以安心地對資料庫進行操作,但是又不用怕會影響資料庫內的資料。
我們可以透過 Model 新增一筆資料,新增的方式有 new
和 create
這兩種方式,這兩種的差別是:
save
存入。new
+ save
book = Book.new(name: "為自己學 Ruby on Rails", content: "作者是高見龍")
book.save
當執行 save
時,Model 會產生以下的 SQL 語法,並將資料寫入 Book 資料表內:
INSERT INTO "books" ("name", "content", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "為自己學 Ruby on Rails"], ["content", "作者是高見龍"], ["created_at", "2022-10-09 05:57:23.328417"], ["updated_at", "2022-10-09 05:57:23.328417"]]
create
book = Book.create(name: "挪威的森林", content: "作者是村上春樹")
它會直接存入資料表中。
不管是 new
或 create
這兩種都會在寫入失敗時回傳「內容是 nil 的 Model 物件」,通常在 Controller 的 Action 裡常會藉此判定資料寫入是否成功。
其實 create
有另一個叫做 create!
的方法,這兩者都會直接把資料存到資料表中,差別是當寫入發生錯誤時,create!
會產生例外(Exception)訊息。
從資料表中讀取資料是非常常見的操作,讀取的方式很多種,有一次只讀取一筆資料,也有一次讀取一整批資料,這邊跟大家介紹一些比較常用的幾種方式。
當我們要查詢第一筆或最後一筆資料可以使用 first
和 last
。
Book.first # 取得 Book 資料表中的第一筆資料
Book.first(5) # 取得 Book 資料表中的第五筆資料
Book.last # 取得 Book 資料表中的最後一筆資料
同場加映:
我們可以使用 all
取得該資料表全部的資料:
Book.all # 取得 Book 資料表中全部資料
當我們想要找到指定 id 的資料時,就可以使用 find
或 find_by
。
Book.find(2)
Book.find_by(id: 2)
這兩種方式都可以找到 id 為 2 的書,差別在於:
find_by
可以把任何在資料表內的資料;find
只能找 id 。find_by
如果找不到指定 id 的資料,只會回傳 nil
;但是 find
則會直接產生 ActiveRecord::RecordNotFound
當找不到資料時的錯誤訊息:
where
會加上一些條件做為篩選:
Book.where("id > 2")
這樣他會搜尋 id 大於 2 的書。
更新資料常見的方法有 save
、 update
、 update_attribute
及 update_attributes
。
book2 = Book.find(2)
使用 save 預設會經過驗證 (validation) ,如果驗證失敗將無法寫入。
如果想要跳過驗證,可以在 Model 加上 validates: false
。
book2.name = "為你自己學 Git"
book2.save
儲存之後:
可以一次更新多個欄位,而且不用呼叫 save 。
book2.update(name: "為你自己學 Git", content: "作者也是高見龍")
跟 update 一樣,只是名字不一樣,做的事情是一樣的。
book2.update_attributes(name: "為你自己學 Git", content: "作者也是高見龍")
這個可以更新單一欄位的值 (方法名稱是單數) 。
而且這個方法會直接跳過驗證 (validation) ,等於 save(validate: false)
。
book2.update_attribute(:name, "為你自己學 Git")
刪除資料可以使用 delete
或 destroy
。
第一步也是一樣要找出你要刪除的資料:
book = Book.find(1)
找到你要的資料之後,就可以把該筆資料刪除了:
book.delete
book.destroy
destroy
跟 delete
的差別:
delete from ...
語法,不會觸發任何回呼。參考資料: