2018/1/11
第二十四天:認識資料庫(續)
昨天我們講到資料模型產生器的用法:
```
rails generate model keyword_mapping keyword message
```
會產生兩個我們需要的檔案:
- 資料庫遷移檔:`db/migrate/20180110181744_create_keyword_mappings.rb`
- 資料模型:`app/models/keyword_mapping.rb`
其中,資料庫遷移檔就像是一張對資料庫施法的卷軸設計圖,可以用來幫資料庫升級。
那要怎麼升級呢?
# 資料庫遷移
使用 `rails db:migrate` 指令就會進行資料庫升級。
```
D:\只要有心,人人都可以作卡米狗\ironman>rails db:migrate
== 20180110181744 CreateKeywordMappings: migrating ============================
-- create_table(:keyword_mappings)
-> 0.4916s
== 20180110181744 CreateKeywordMappings: migrated (0.4927s) ===================
D:\只要有心,人人都可以作卡米狗\ironman>
```
還可以用 `rails db:rollback` 降級:
```
D:\只要有心,人人都可以作卡米狗\ironman>rails db:rollback
== 20180110181744 CreateKeywordMappings: reverting ============================
-- drop_table(:keyword_mappings)
-> 0.5057s
== 20180110181744 CreateKeywordMappings: reverted (0.5211s) ===================
D:\只要有心,人人都可以作卡米狗\ironman>
```
可以用 `rails db:migrate:status` 查看目前等級。這是升級前:
```
D:\只要有心,人人都可以作卡米狗\ironman>rails db:migrate:status
database: D:/只要有心,人人都可以作卡米狗/ironman/db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
down 20180110181744 Create keyword mappings
D:\只要有心,人人都可以作卡米狗\ironman>
```
這是升級後:
```
D:\只要有心,人人都可以作卡米狗\ironman>rails db:migrate:status
database: D:/只要有心,人人都可以作卡米狗/ironman/db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20180110181744 Create keyword mappings
D:\只要有心,人人都可以作卡米狗\ironman>
```
資料庫已就緒,接下來就只等我們把學習紀錄寫入了。接下來我會試著用 [Google 試算表](https://www.google.com/intl/zh-TW_tw/sheets/about/)來比喻目前資料庫的狀態(因為我家沒有 Excel),現在的資料庫看起來像這樣:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEickLSuTINz3yHZ5q7CnPiF_T8L3ol03H_B9QD6aZTgXcgcRjTadqjjKvohbY7B9tL1wLPnDrDHwl6xMSeCJ9nBUO_1BLlp6-lDVJmFFgcLLXm7J0a0kePKxQPBKkRuOf55Ivb79LRI4qc/s1600/1.jpg)
# 資料模型
我們可以使用 `rails console` 或簡寫 `rails c` 去試著操作看看資料模型, `rails console` 是一個類似 `irb` 的互動式介面,他可以讓你輸入一行程式就立即生效。
```
D:\只要有心,人人都可以作卡米狗\ironman>rails console
Loading development environment (Rails 5.1.4)
irb(main):001:0>
```
### 列出所有資料
我們的資料模型叫做 `KeywordMapping`。可以用 `.all` 將它顯示出來看看:
```
irb(main):001:0> KeywordMapping.all
KeywordMapping Load (2.5ms) SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ? [["LIMIT", 11]]
=> #
irb(main):002:0>
```
這一段:
```
SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ?
```
是我們對資料庫進行查詢的 SQL 語法,幸好你不需要學會這個,就當作沒看到吧。
而這一段:
```
=> #
```
是指 `KeywordMapping.all` 是一個 `ActiveRecord::Relation` 類別的實體, `[]` 表示它是空的。
讓我們弄點東西進去。
### 新增資料
用 `KeywordMapping.new` 可以獲得一筆新的空白資料。
```
irb(main):002:0> new_data = KeywordMapping.new
=> #
irb(main):003:0>
```
用一個變數 `new_data` 去接住它,因為我們接下來要對他做事。
```
irb(main):003:0> new_data.keyword = "Q"
=> "Q"
```
設定 new_data 的 keyword 是 "Q"。
```
irb(main):004:0> new_data.message = "A"
=> "A"
irb(main):005:0>
```
設定 new_data 的 message 是 "A"。
都設定好之後用 `new_data.save` 來存檔。
```
irb(main):005:0> new_data.save
(0.0ms) begin transaction
SQL (494.1ms) INSERT INTO "keyword_mappings" ("keyword", "message", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["keyword", "Q"], ["message", "A"], ["created_at", "2018-01-11 14:30:55.567172"], ["updated_at", "2018-01-11 14:30:55.567172"]]
(52.5ms) commit transaction
=> true
irb(main):006:0>
```
一樣,就是一堆不需要看懂的 SQL。現在使用 `KeywordMapping.all` 就能看到新加入的資料了。
目前資料表的狀態:
```
irb(main):006:0> KeywordMapping.all
KeywordMapping Load (0.0ms) SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ? [["LIMIT", 11]]
=> #]>
irb(main):007:0>
```
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkE0jCHbZillsWuf2MYvDXyzLpJGKfqt6Ow49-QI2SjGA7FlpbcIaRR93ijS24lMv6VPzWfx_ft4pvSDlfRJxnls2W0PrwZxjY1-ri1kHGCgLn_2RoXXrOJDJAo6P0l7oldkNRdbxiaYw/s1600/2.jpg)
新增資料也有簡寫的方式可以一行做完,指令是 `KeywordMapping.create({keyword:"Q2", message:"A2"})`:
```
irb(main):007:0> KeywordMapping.create(keyword:"Q2", message:"A2")
(0.0ms) begin transaction
SQL (485.4ms) INSERT INTO "keyword_mappings" ("keyword", "message", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["keyword", "Q2"], ["message", "A2"], ["created_at", "2018-01-11 14:36:34.858893"], ["updated_at", "2018-01-11 14:36:34.858893"]]
(48.5ms) commit transaction
=> #
irb(main):008:0>
```
這是傳入一個 hash 作為設定,用 `create` 方法的話就會自動 `save`,所以就不用自己再打 `save` 了。
目前資料表的狀態:
```
irb(main):009:0> KeywordMapping.all
KeywordMapping Load (0.0ms) SELECT "keyword_mappings".* FROM "keyword_mappings" LIMIT ? [["LIMIT", 11]]
=> #, #]>
irb(main):010:0>
```
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaVO4FJfMRkqihoMfkBGqYh8EjY_lJhNh7gL_zR9UTh3aZbIyVu7G5y7AHrF7DStxx0R2w62vcR2szqN822SCYNe6v3UjUsBJRRpkzMoGmaRImwEwIb2wEsr2UH6zu-PUO08Ua-FeoH-A/s1600/3.jpg)
### 查詢資料
我們通常不會想要拿出整個資料表,而是只想要查當中的一筆,這時候就要用 `where` 方法,以下示範 `KeywordMapping.where(keyword:"Q2")`。
```
irb(main):008:0> KeywordMapping.where(keyword:"Q2")
KeywordMapping Load (0.5ms) SELECT "keyword_mappings".* FROM "keyword_mappings" WHERE "keyword_mappings"."keyword" = ? LIMIT ? [["keyword", "Q2"], ["LIMIT", 11]]
=> #]>
irb(main):009:0>
```
這是篩選功能,我們對 `keyword` 欄位做 `Q2` 篩選,在 Google 試算表按照順序點就可以達到相同的效果。
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUURzgRjIKIolm51sGciqE7YjmnesYZBadibFRZS9v3lfm-DtqbNBD3RthlmOtSng6bNfNnx3Zf_ok5KWGBSXxG8VLlZ096Y6aUG54Vprsiw4pu4iDns-Sc4RSIqtpJCR6g6gWr1AB_-E/s1600/4.jpg)
篩選出來可能會有多筆,我們可以 `.all` 取得全部或者 `.first` 取第一筆,或 `.last` 取最後一筆。
所以卡米狗觸發教學的寫法是這樣:`KeywordMapping.where(keyword:"Q2").last.message`,對 `keyword` 欄位做篩選,找到最後一次教學紀錄,然後取出 `message` 欄位的內容。
```
irb(main):012:0* KeywordMapping.where(keyword:"Q2").last.message
KeywordMapping Load (0.5ms) SELECT "keyword_mappings".* FROM "keyword_mappings" WHERE "keyword_mappings"."keyword" = ? ORDER BY "keyword_mappings"."id" DESC LIMIT ? [["keyword", "Q2"], ["LIMIT", 1]]
=> "A2"
irb(main):013:0>
```
丟 Q2 進去資料庫查,查到 A2 再回應給 Line。
# 本日重點
- 學會使用資料庫遷移
- 學會使用資料模型
- 了解卡米狗觸發教學的原理
明天會講怎麼用這兩天學到的東西做出卡米狗學習指令。
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言