iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 23
2

我們預計下一個要完成的功能是教學指令。

這是昨天的關鍵字回覆:

# 關鍵字回覆
def keyword_reply(received_text)
  # 學習紀錄表
  keyword_mapping = {
    'QQ' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s',
    '我難過' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s'
  }
  
  # 查表
  keyword_mapping[received_text]
end

其中的學習紀錄表應該要能隨著大家講的話而去新增內容。這表示學習紀錄表應該要保存在檔案或資料庫內,每當需要存取學習紀錄表時就去存取檔案或資料庫。

今天講資料庫應該就飽了。

安裝 postgresql

查了一下發現是一條艱難的路,postgresql 在 Windows 上安裝的過程太過繁瑣,這裡就跳過不講,我們可以選擇在開發環境使用 sqlite3,同時在 Heroku 上使用 postgresql。當然你要挑戰在開發環境使用 postgresql 也行。這裡提供一個連結給你參考一下:https://stackoverflow.com/questions/11656410/postgresql-installation-failed,是不是令人看了就想崩潰呢~如果是 macOS 的話瞬間就裝完囉。

設定 database.yml

我們要修改的檔案位於 config/database.yml
這是一開始的樣子:

# SQLite version 3.x
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
#
default: &default
  adapter: postgresql
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3

要改成這樣:

# SQLite version 3.x
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
#
default: &default
  adapter: postgresql
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  adapter: sqlite3
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  adapter: sqlite3
  database: db/test.sqlite3

production:
  <<: *default
  database: ironman

先解釋一下,這裡有四段程式(其實不是程式,是設定檔)。

這是第一段:

default: &default
  adapter: postgresql
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

這是作為一個預設值。

  • adapter:要採用哪一套資料庫,預設使用 postgresql
  • pool:是同時連線數量,可以理解成頻寬
  • timeout:超過 5000 毫秒資料庫還不回應的話就當作逾時
development:
  <<: *default
  adapter: sqlite3
  database: db/development.sqlite3

這段是開發環境,也就是我們的電腦。

  • <<: *default:採用預設值
  • adapter:要採用哪一套資料庫,這裡是使用 sqlite3,會把預設值覆蓋掉
  • database:資料庫的儲存位置,db/development.sqlite3 這是一個路徑,你可以在專案資料夾裡面找到這個位置
test:
  <<: *default
  adapter: sqlite3
  database: db/test.sqlite3

這段是測試環境,目前我們沒有使用測試環境,所以這裡跳過不講。

production:
  <<: *default
  database: ironman

這段是發布環境或正式環境,也就是 heroku 上。

  • database:使用 postgresql 的話就不是儲存位置了,而是資料庫的名稱,不過概念上差不多。和 sqlite3 的差別是你不會在專案資料夾裡頭找到資料庫的實體檔案。

設定 Gemfile

因為我們要在 development 環境下使用 sqlite3,production 環境下使用 postgresql,所以 Gemfile 也要改寫,這是原本的 Gemfile:

gem 'pg', '~> 0.21.0'

要改寫為

group :development, :test do
  gem 'sqlite3'
end

group :production do
  gem 'pg', '~> 0.21.0'
end

意思就是在 development 和 test 環境下要使用 sqlite3,而在 production 環境下使用 postgresql

建立資料庫

在小黑框輸入:

rails db:create

就可以得到一個空白的資料庫,你可以觀察它會出現在專案資料夾下的 db 資料夾下。

建立資料表

在小黑框輸入:

rails generate model keyword_mapping keyword message

會看到:

D:\只要有心,人人都可以作卡米狗\ironman>rails generate model keyword_mapping keyword message
      invoke  active_record
      create    db/migrate/20180110181744_create_keyword_mappings.rb
      create    app/models/keyword_mapping.rb
      invoke    test_unit
      create      test/models/keyword_mapping_test.rb
      create      test/fixtures/keyword_mappings.yml

D:\只要有心,人人都可以作卡米狗\ironman>

表示有四個檔案被生成了,分別是:

  • 資料庫遷移檔:db/migrate/20180110181744_create_keyword_mappings.rb
  • 資料模型:app/models/keyword_mapping.rb
  • 單元測試:test/models/keyword_mapping_test.rb
  • 測試資料:test/fixtures/keyword_mappings.yml

因為我們不寫自動測試,所以後面兩個就先略過。

資料庫遷移檔

一個資料庫會有多個資料表,一個資料表會有多個欄位。以通訊錄為例,欄位大概就是姓名、電話、地址、信箱等等。大概長這樣:https://goo.gl/VMT3CR

建立一個空的資料表需要定義出這個表格有哪些欄位,分別儲存什麼格式的資料。

假設你現在在人工建立表格,你可能會開啟一個 Excel 然後在第一列上面輸入各種標題,說明下面每個格子該填什麼。但是工程師最不喜歡手動做事了,自動化就是潮。所以我們寫一隻程式去幫我們建立資料庫裡的表格,這些程式碼被稱為資料庫遷移檔。

但是工程師連資料庫遷移檔也懶得寫,所以就寫了一行指令自動生成資料庫遷移檔,也就是你剛剛輸入的那個指令。

打開 db/migrate/20180110181744_create_keyword_mappings.rb 會看到:

class CreateKeywordMappings < ActiveRecord::Migration[5.1]
  def change
    create_table :keyword_mappings do |t|
      t.string :keyword
      t.string :message

      t.timestamps
    end
  end
end

重點在這裡:

    create_table :keyword_mappings do |t|
      t.string :keyword
      t.string :message

      t.timestamps

建立一個資料表叫 keyword_mappings,資料表包含兩個欄位,分別是 keywordmessage,都是存字串。

資料模型

打開 app/models/keyword_mapping.rb 會看到:

class KeywordMapping < ApplicationRecord
end

空的,因為它用繼承 (<),其實有很多東西是藏在 ApplicationRecord 裡面。

所以我們剛剛輸入的指令是這樣:

rails generate model keyword_mapping keyword message

意思是我要生成一個資料模型和資料庫遷移檔,資料表名稱為 keyword_mapping,包含兩個欄位分別是 keywordmessage

今天先講到這裡。

資料庫博大精深,卡米狗不是一天造成的,要有耐心。


上一篇
第二十二天:用 Line Messaging API 實作關鍵字回覆
下一篇
第二十四天:認識資料庫(續)
系列文
只要有心,人人都可以做卡米狗33
0
0
ninjazyx
iT邦新手 5 級 ‧ 2018-01-31 14:54:20

卡米大 這路徑好像錯了?

測試資料:test/models/keyword_mapping_test.rb

感謝抓錯

0
rk42745417
iT邦新手 5 級 ‧ 2018-06-29 21:55:44

我們給的名稱是
keyword_mapping
他的資料模型變成
KeywordMapping
他的遷移檔變成
keyword_mappings
???

對的 它會自動變成複數型

我要留言

立即登入留言