框架終於有一點雛形了
相關的 gem 也都安裝完成了
接下來就是做 Controller 啦!
首先,我們先將 version 升成 0.0.2
變更 version
module Rainbow
VERSION = "0.0.2"
end
> gem build rainbow.gemspec
Successfully built RubyGem
Name: rainbow
Version: 0.0.2
File: rainbow-0.0.2.gem
> gem install rainbow-0.0.2.gem
Successfully installed rainbow-0.0.2
Parsing documentation for rainbow-0.0.2
Installing ri documentation for rainbow-0.0.2
Done installing documentation for rainbow after 0 seconds
1 gem installed
> bundle update rainbow
Rainbow 設定 Controller
當請求抵達 web server 及 application server 時
Rack 會把程式碼傳過去,這時候需要知道哪個 Controller 及 action 要處理這個請求
# /rainbow/lib/rainbow.rb
require "rainbow/routing"
module Rainbow
class Application
def call(env)
# Controller 是 class,而 class 為保留字,所以這邊用 klass 代替
klass, act = get_controller_and_action(env)
controller = klass.new(env)
text = controller.send(act)
[
200,
{'Content-Type' => 'text/html'},
# 記得這裡要換成 text
[text]
]
end
class Controller
# 初始化載入環境變數
def initialize(env)
@env = env
end
def env
@env
end
end
end
end
web小辭典
▶ Rack Env: 一個 hash 物件,裡面含有 HTTP request、rack資訊、其他資訊(ex. WEBRick增加的資料)
▶ PATH_INFO: 以偽靜態頁面方式運作,不包含 query 參數(放置於?後面)的 URL,會告訴 Rails 要用哪個 Controller 跟 action
Rainbow 設定 routing
在 rainbow/lib/rainbow 新增 routing.rb
設置路徑,把路徑拆開拿到 Controller 及 action
# /rainbow/lib/rainbow/routing.rb
module Rainbow
class Application
def get_controller_and_action(env)
# 把路徑分成四份,分為 Controller前 / Controller / action /剩下的
_, cont, action, after = env["PATH_INFO"].split('/', 4)
# 首字轉大寫,剩下轉小寫 ex."Quotes"
cont = cont.capitalize
# 加上 Controller ex. "QuotesController"
cont += "Controller"
# const_get 會去尋找大寫開頭的 Controller class
[Object.const_get(cont), action]
end
end
end
是不是很像在 Rails 中的 Controller 呢
現在我們要設定 Controller 並加入 action
# /quotation/app/controller/quotes_controller.rb
class QuotesController < Rainbow::Controller
def a_quote
"You Only Live Once, " + "hang on to your dreams."
end
end
我們還沒在 Controller 加入 Rails autoloading
所以在 config/application.rb 中設定 LOAD_PATH 並把 Controller 載入
# quotations/config/application.rb
# 檔案路徑加入 app/controllers 讓 routes 知道要找哪個 Controller 跟 action
$LOAD_PATH << File.join(File.dirname(__FILE__),
"..", "app", "controllers")
require "quotes_controller"
web小辭典
▶ Rails autoloading: 使用 require 載入文件時,Ruby 會去找 $LOAD_PATH 並把對應的檔名找出來,後面會更詳細的介紹
> gem build rainbow.gemspec
Successfully built RubyGem
Name: rainbow
Version: 0.0.2
File: rainbow-0.0.2.gem
> gem install rainbow-0.0.2.gem
Successfully installed rainbow-0.0.2
Parsing documentation for rainbow-0.0.2
Done installing documentation for rainbow after 0 seconds
1 gem installed
Quotation 終端機啟用 rackup
rackup -p 3001
http://localhost:3001/quotes/a_quote
就會看到quote在畫面上囉
錯誤訊息
回來看終端機,會發現出現了一行錯誤訊息
NameError: wrong constant name Favicon.icoController
瀏覽器會自動讀取favicon.ico
但暫時先用避開的方法處理
# rulers/lib/rulers.rb /module Rainbow
class Application
def call(env)
if env['PATH_INFO'] == '/favicon.ico'
return
[
404,
{'Content-Type' => 'text/html'},
[]
]
end
klass, act = get_controller_and_action(env)
controller = klass.new(env)
text = controller.send(act)
[
200,
{'Content-Type' => 'text/html'},
[text]
]
end
end
基本的 routing、Controller、action 建立好囉
我們明天來建立 debug 功能!