前面的章節有提到過 Model 其實就是一個幫忙與資料庫溝通的地方,他既不是資料庫(Database)也不是資料表(Table),Model 可以當成一個抽象類別,負責跟實體的資料表溝通。
先來簡單說文解字一下這四個基本的字,"CRUD"的意義吧!主要是描述下面這四個字。
我們可以透過基本的 ORM 操作來感受一下rails 如何用到上面的這些操作資料的動作吧,操作前先簡單解釋一下相關的專有名詞,也是許多面試常常會問到的觀念。
ORM 是 Object Relational Mapping 的縮寫,翻譯成「物件關聯對映」。如果想要存取資料庫裡的內容,在以前必須自己撰寫資料庫查詢語言(SQL)對資料庫進行查詢,但透過 ORM 的技術包裝之後,可以讓我們用操作「物件」的方式來操作資料庫。
Active Record 是一種設計模式,MVC 中的 Model 就是根據 Active Record的 模式設計出來的,另外一種常見的說法是 Active Record 是 ORM 的實作方式。
我們先建立一個文章Article 的 Model,在終端機輸入下面指令就可以建立,同時也定義 2 個欄位給他,分別是
title
content
rails g model Article title:string content:text
會產生對應的資料表,我們可以在 app/db 下面看到 migration 檔案,migration 會記錄建立 table 的經過,具備哪些欄位,我們在輸入 db:migrate 將 table 具現化,才能對裡面的內容進行操作
class CreateArticles < ActiveRecord::Migration[6.1]
def change
create_table :articles do |t|
t.string :title
t.text :content
t.timestamps
end
end
end
從上面看似乎還會有timestamps 這個資料欄位,但其實總共還會多出 id
、timestamps
,timestamps 在經過轉換之後,會產生兩個名為 created_at 跟 updated_at 的時間欄位,分別會在資料「新增」及「更新」的時候,把當下的時間寫入,可以作為一個紀錄,讓你知道某筆資料的變動。
id 欄位則是在 Migration 沒辦法看到任何資訊,因為這是 Rails 自動幫每個資料表加的流水編號欄位,也稱為資料表的主鍵(Primary Key)。方便讓你知道目前這個 table 建立過幾筆資料,查找上也會比較方便。
可以從下面預設的app/db/development.sqlite3 的檔案看到實際所有的欄位
可以從rails console 裡面來操作實際建立一筆資料,終端機輸入 rails console
or rails c
之後
我們可以使用 active record 提供給我們的方法
3.0.0 :001 > Article.create(title:"文章1",content:"進入ruby世界說hello world")
(0.3ms) SELECT sqlite_version(*)
TRANSACTION (0.0ms) begin transaction
Article Create (0.4ms) INSERT INTO "articles" ("title", "content", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["title", "文章1"], ["content", "進入ruby世界說hello world"], ["created_at", "2022-10-03 12:41:21.833091"], ["updated_at", "2022-10-03 12:41:21.833091"]]
TRANSACTION (0.4ms) commit transaction
=> #<Article id: 1, title: "文章1", content: "進入ruby世界說hello world", created_at: "2022-10-03 12:41:21.833091000 +0000", updated_at: "2022-10-03 12:41:21.833091000 +0000">
可以看到上面 有出現 INSERT INTO "articles" 這個 SQL 語法,表示已經將檔案寫入資料庫
想要取得資料表中的第一筆或最後一筆資料,可使用 first
或 last
方法,我們用 last 來讀看看
4.3.0.0 :002 > a1 = Article.last
Article Load (0.5ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."id" DESC LIMIT ? [["LIMIT", 1]]
=> #<Article id: 1, title: "文章1", content: "進入ruby世界說hello world", created_at: "2022-10...
4.3.0.0 :003 > a1
=> #<Article id: 1, title: "文章1", content: "進入ruby世界說hello world", created_at: "2022-10-03 12:41:21.833091000 +0000", updated_at: "2022-10-03 12:41:21.833091000 +0000">
讀取最後一筆 (目前也只有一筆) 資料並且放入變數 a1 中,可以看到顯示出所有這筆資料的欄位及值,除了我們說的定義的欄位之外還有多出那 3 個前面提到的欄位。
我們也用一下 new 方法讓大家看一下,需要再用 save 進行資料的寫入
3.0.0 :001 > a2 = Article.new(title:"文章2", content:"CRUD是什麼?")
(0.6ms) SELECT sqlite_version(*)
=> #<Article id: nil, title: "文章2", content: "CRUD是什麼?", created_at: nil, updated_at: nil>
4.3.0.0 :002 > a2.save
TRANSACTION (0.2ms) begin transaction
Article Create (1.1ms) INSERT INTO "articles" ("title", "content", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["title", "文章2"], ["content", "CRUD是什麼?"], ["created_at", "2022-10-04 09:31:49.206583"], ["updated_at", "2022-10-04 09:31:49.206583"]]
TRANSACTION (0.8ms) commit transaction
=> true
看到 save 之後有回傳一個 true 表示有成功寫入。
也可以來用 first 抓看看我們的資料,先用 Article.all 看一下全部是有兩筆資料,然後可以用 first,也可以用 first(number),括號內可以指定要從第一筆開始抓幾筆。
3.0.0 :004 > Article.all
Article Load (0.5ms) SELECT "articles".* FROM "articles" /* loading for inspect */ LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Article id: 1, title: "文章1", content: "進入ruby世界說hello world", created_at: "2022-10-03 12:41:21.833091000 +0000", updated_at: "2022-10-03 12:41:21.833091000 +0000">, #<Article id: 2, title: "文章2", content: "CRUD是什麼?", created_at: "2022-10-04 09:31:49.206583000 +0000", updated_at: "2022-10-04 09:31:49.206583000 +0000">
3.0.0 :004 > Article.first
Article Load (0.3ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Article id: 1, title: "文章1", content: "進入ruby世界說hello world", created_at: "2022-10-03 12:41:21.833091000 +0000", updated_at: "2022-10-03 12:41:21.833091000 +0000">
4.3.0.0 :005 > Article.first(2)
Article Load (0.3ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."id" ASC LIMIT ? [["LIMIT", 2]]
=> [#<Article id: 1, title: "文章1", content: "進入ruby世界說hello world", created_at: "2022-10-03 12:41:21.833091000 +0000", updated_at: "2022-10-03 12:41:21.833091000 +0000">, #<Article id: 2, title: "文章2", content: "CRUD是什麼?", created_at: "2022-10-04 09:31:49
下篇再來繼續說明一些讀取的方法、更新及刪除的部分。
---
參考資料: