完成 view 以及 controller 後
我們就要來做 model 拉!
我們的 model 會以 file 為基礎,會使用 JSON 文件格式
加入 multi_json 套件
# rainbow/rainbow.gemspec
gem.add_runtime_dependency "rack"
gem.add_runtime_dependency "erubis"
gem.add_runtime_dependency "multi_json"
end
Rails 的許多應用程式及函式庫是基於套件而建構而成
當我們在部署大型專案時,不需要安裝好幾個套件,讓整個系統保持乾淨、簡潔
安裝 multi_json
> bundle install
我們用 JSON 主要是因為好讀、好寫的特性
來看一下,我們該怎麼建立一個 JSON 物件
{
"submitter": "Jeff",
"quote": "A penny saved is a penny earned.",
"attribution": "Ben Franklin"
}
接下來我們來建立 db
建立 best_quotes/db/quotes,其中 db 會作為資料庫
quotes 子資料夾會包含一個表格
裡面有 quote 的 JSON 資料
在這之前,我們需要先建一個 Rainbow 物件
打開 rainbow/lib/rainbow.rb
增加一個套件 file_model
# rainbow/lib/rainbow.rb (excerpt)
require "rainbow/dependencies"
require "rainbow/controller"
require "rainbow/file_model"
打開 rainbow/lib/rainbow/file_model.rb
# rainbow/lib/rulers/file_model.rb
require "multi_json"
module Rainbow
module Model
class FileModel
def initialize(filename)
@filename = filename
# If filename is "dir/37.json", @id is 37
basename = File.split(filename)[-1]
@id = File.basename(basename, ".json").to_i
obj = File.read(filename)
@hash = MultiJson.load(obj)
end
def [](name)
@hash[name.to_s]
end
def []=(name, value)
@hash[name.to_s] = value
end
def self.find(id)
begin
FileModel.new("db/quotes/#{id}.json")
rescue
return nil
end
end
end
end
end
初始化時,我們把檔案做切分,然後取最後一個
MultiJson 可以從 Ruby hash 做簡單的編碼及解碼,他會以多工的方式進行解碼,跟 Rails 運作機制一樣
我們有一個 square-bracket 方法,所以可以做到像 Rails 中的 hash 引用 key 的模式
你可以寫 obj["field"] 而不是 obj.field
在 Active Record 中,你會根據參數或者 ID 建立一個物件
假設是使用 ID 來建立,你就得先尋找這個物件的 ID
我們來快速看一下 self.find(id) ,他會幫我們去搜尋物件的 id
假設我們在字串中插入 #{},他會自動把裡面的東西轉換成字串
如果 find() 找不到 id ,就會回傳 nil
Ruby 會用 FileNotFound 來解決這個意外
所以找不到的時候,我們要來設定 RecordNotFound 作為 exception
# best_quotes/app/controllers/quotes_controller.rb
class QuotesController < Rulers::Controller
# (excerpt)
def quote_1
quote_1 = Rainbow::Model::FileModel.find(1)
render :quote, :obj => quote_1
end
end
再來用 view 來渲染
<%# best_quotes/app/views/quotes/quote.html.erb %>
<p>
"<%= obj["quote"] %>"
<br/> – <%= obj["attribution"] %>
</p>
<p>
Submitted by <%= obj["submitter"] %>
</p>
現在,我們到 best_quotes 做 bundle
把 multi_json 這個套件加進來
重啟 server
http:// localhost:3001/quotes/quote_1
Model 就這樣建立好囉!
讓 controller 擴充 model 的方法
打開 rainbow/lib/rainbow/controller.rb
在上面加一個 require
# rainbow/lib/rainbow/controller.rb (excerpt)
require "rainbow/file_model"
module Rainbow
class Controller
include Rainbow::Model
#...
end
end
現在我們可以搜尋物件的 id
ActiveRecord 也提供了 find all 方法
打開 rainbow/lib/rainbow/file_model.rb
用 map 來對 files 裡的每個資料做一個做出新的實體
module Rainbow
module Model
class FileModel
def self.all
files = Dir["db/quotes/*.json"]
files.map { |f| FileModel.new f }
end
end
end
end
打開 best_quotes/app/controllers/quotes_controller.rb
增加一個 index 方法
# best_quotes/app/controllers/quotes_controller.rb
class QuotesController < Rainbow::Controller
def index
quotes = FileModel.all
render :index, :quotes => quotes
end
end
新增一個新的 view
<%# best_quotes/app/views/quotes/index.html.erb: %>
<% quotes.each do |q| %>
<p> <%= q["quote"] %> </p>
<% end %>
這樣就完成囉