Ruby on Rails 實踐

看到一篇好文章 但由於原來格式爲PDF 考慮不便於網絡傳播 便改成了web形式發佈,並更正了原文部分bug,文中作者信息均爲原作者信息。

Ruby on Rails 實踐


Java 框架到底怎麼了?


如果你作爲一個 Java 程序員從事 j2ee 開發的話,你一定會使用到衆多應用程序框架。沒有 任何一個語言會象 java 語言社區那樣活躍,任何一種新的程序理念都會很快在網上出現相 應的開源實現。對應最常用的網站開發模式MVC,每一層都會有很多框架,Struts, Tapestry 屬於控制器層(C), Velocity 框架屬於視圖層(V), 你使用的數據持久層可能是 Hibernate, iBatis, OJB, 或者是 JDO 的衆多開源實現中的任何一個,比如 JPOX 。 但是你的選擇太 多,未必是件好事,並不是任何人都能採用正確的框架來做正確的事情。如果你的開發平臺
是 .net, 那麼你也許會避免這種情況,通常你只要安裝一個 Visual Studio .net 作爲開發工 具,然後安裝一個 MSDN 來查找資料就可以了。對於程序開發人員來說,這是非常兩難的 事情。我本人很喜歡 Java ,無論是學習還是實踐,它的確給我們提供了很多。但是爲什麼 我覺得 .net 那樣“一站式”解決方案在很多時候是正確的呢?


作爲一個 Java 程序員,我覺得 Java 一些比較明顯的問題,首先是 Java 太複雜,其次 Java 太 面向程序員了,而不是面向用戶。相對 C++ 來說, Java 已經很簡單了。現在 Java 程序 員數量如此多就說明了這點。但是正如有人曾經說過的那樣,“在 linux 上,你很容易區分 出誰是高手”,在 Java 領域中就不那麼容易了。我就經常發現身邊的同事還在犯很低級的 概念性錯誤,他們甚至在無法準確地區分什麼是接口,抽象類和 Servlet 的情況下仍然可以 從事多年的 j2ee 開發。但爲什麼又說 Java 複雜呢,因爲它完成一件事情,需要太多不同 的技術來實現了。這樣對於那些概念不很清楚的程序員來說,你如何能保證他們作出正確的 選擇呢?而衆多框架中有沒有多少提供“一站式”服務的。最近冒頭的 Spring 框架提供的 服務在衆多的框架中算是最多的了,但是它又有個新問題,就是它還是太面向程序員了,而 不是用戶。爲什麼這麼說呢?框架本來就是面向程序員的,這難道不對嗎?Spring 雖然提 供了衆多選擇(但是還是不夠多,它本身沒有 ORM ),但它沒有提供簡單的使用方式,所以 我們只能說它是面向程序員的。絕大多數 java 框架都存在這個問題,就是學習曲線比較高。 我覺得學習曲線的高低是區分一個框架是否是面向程序員還是用戶的關鍵,我想這主要表現 在框架的易用性上。其實框架最終的用戶還是程序員,之所以用“用戶”和“程序員”來區 分,是因爲一些面向“程序員”的框架比較難以使用,雖然提供了大量的基礎設施和零件, 但是還是要求程序員自己來組裝。而面向“用戶”的框架就簡單一些,用戶只要按照說明書 來使用就可以了。爲什麼 Ruby on rails 會在 Java 社區引發轟動,我想原因就在於此,它 提供了一個“一站式”面向用戶的簡單易用的框架,這是 java 框架所缺乏的。爲什麼 Ruby
on rails 能做到這點,難道 java 本身做不到嗎? 事實是衆多 Java 框架的設計者不這麼做, 可能是他們的思維已經限制在如何用模式設計一個好的框架上了,而沒有在框架的易用性上 做更多文章。使用過 Spring 的人就知道它的 xml 配置文件會漸漸的膨脹,雖然我們很容 易將其分解爲更多的小配置文件來解決這個問題。 但是在使用 xml 配置文件上,它沿襲
了 Java 編程的習慣性概念:“Java 是最好的編程語言,XML 是最好的描述數據的語言, 兩者的結合是最完美的。如果一個應用不使用 xml 來描述,那麼它就不是好的 java 應用”。
但是 ruby on raiils 就是在這點上和衆多 java 框架區別開來,才達到了框架易用性上的一次 突破。這個思想貫穿了 Rails 設計的始終:習慣約定優於配置。 舉個例子,通常我們寫 java web 應用程序,都會按照 MVC 來給對應類做區分,我個人喜歡將 Controller 類放在 web 目錄中,將 View 類放在 view 目錄中,將 model 類放在 domain 目錄中。但是不同的人 有不同的設置,不同的命名,如何讓框架知道這些不同的目錄呢, java 框架的解決之道, 只能是通過 xml 配置文件讓它瞭解這些信息。而 rails 的解決方式就是: 目錄結構我來定 義,你只要在我定義好的目錄中放東西就可以了。 這也就是爲什麼 rails 中很少有配置文 件(但不是沒有)的一個重要原因。雖然思想很簡單,但是它帶來的好處就是,Rails 的開 發效率是 java 開發的 10 倍(這是 rails 的 fans 宣稱的,不過我相信這點,相信看完這篇 文章你也一定會的)。那麼光這點就能讓 rails 開發比採用 java 更快了嗎?不完全是這樣, 因爲這還得益於 rails 的另外一個設計理念:更少的代碼。 並不是任何語言都能那麼宣稱 的,rails 實現這點完全得益於它的設計語言 Ruby 。使用 Ruby 你的確能用很少的語言寫 很多的功能,這是其他語言所無法實現的。 想要掌握 Rails,你一定要了解 Ruby。 曾經有 人說:Zope (著名的 python web 框架)是 python 的 killer 級應用,python 是 zope 的祕密 武器。 我想這句話用在描述 rails 和 ruby 的關係再合適不過了。那麼我們還是來先了解 一下 ruby 的一些基本概念吧。

 


Ruby 簡介:


在開始寫這個教程之前,我原打算簡單介紹一下 Rails 的使用就可以了,網上有相應的教 程,只要照着翻譯一遍就行。但是有兩個原因促使我要先介紹一下 ruby: 一是:作爲一個 Ruby 語言的愛好者,我覺得有必要向大家介紹它的好處。它是學習 Rails 的關鍵所在。二 是:不先學習一些 Ruby 的基本知識,Rails 一些代碼你就會不明白原委。


Ruby 是由日本人松本行弘發明的一種面向對象的腳本語言。雖然很多語言都宣稱自己是面 向對象的,但是每種語言的解釋都不一樣,大多是以它們自己特有的方式來解釋什麼是面向 對象,而實際情況中,這些面嚮對象語言又都採用了很多非面向對象的做法。以 Java 爲例: 如果你想對一個數字取絕對值,你會怎麼做呢? java 的做法是
int c = Math.abs(-166);

也就是將一個數值傳遞給 Math 類的一個靜態函數 abs 處理。爲什麼這麼做?因爲在 java
中, 數值是基本類型不是類。


而在 Ruby 中,任何事物都是類, 也就是說,數字 –166 就是對象,取絕對值這樣的操作 應該屬於數字本身,所以”Ruby 方式”的做法就是:


c = -166.abs

這種做法是不是更直觀一點。

接着我們來介紹一下 ruby 語言的一些簡單特點。
如何定義函數


def hello(name)
result = "hello, " + name return result
end


這就是一個最簡單的函數定義。Ruby 以 def 開始一個函數定義,後跟着 函數名, 然後是 參數,但是參數不必非要放在括號中, 你可以這樣定義 def hello name ,之所以要用括號 是爲了更清晰。在 ruby 中你可以用多種方式來完成同一件事情,這也是 ruby 的設計思想。


Hello 函數很簡單, 將參數和 “hello, “字符串組合在一起,賦值給臨時變量 result ,然後 再返回 result。 你會注意到 result 變量並沒有申明,因爲在 ruby 中無需申明,變量在賦 值中自動使用。 另外 ruby 中不需要使用 ; 來結束每個語言,只要保持每條語句在單獨一 行就可以。 Ruby 也不包含 {} 來定義塊結構, if , when 函數都以一個 end 關鍵字來結 束。縮進不是語法(python 程序員要失望了)。第一次使用 ruby 我也有點不習慣,因爲我 認爲 python 語言的縮進語法可以使得閱讀程序代碼更容易一些。但是學習了一段時間後, 我發現縮進語法並不是那麼重要,Ruby 本身帶來的幫助遠比這個更重要。而且代碼的易讀 性也不是由縮進來改善的.此外上面的代碼還可以更簡化。


def hello (name)
" hello, #{name}"
end


在 ruby 中,函數的最後一條語句如果是表達式,那麼它就作爲返回值。在上面的代碼中, 用到了另外一個概念,就是表達式插入,字符串可以用單引號和雙引號來括起來。但是兩者 還是有一點區別。區別在於處理時間上的不同。如果使用單引號,那麼處理的時間很短。如 果使用雙引號,那麼你可以插入變量,表達式,還有就是轉意字符的替換,最常見的是 n,
t 等。 以上面的代碼爲例 字符串中插入了變量 name ,字符串中插入變量以 # 開始,變 量放在{}中。 但是特殊變量可以不用 {}. 那麼什麼是特殊變量呢。這個也是 ruby 特別的 地方。在 Ruby 中,全局變量以 $開頭,靜態變量,也就是類變量以 @@ 開頭,實例變量
以 @ 開頭。如果在字符串中引用 實例變量,你可以這麼寫。


def hello
" hello, #@name"
end

關於變量和基本結構我們就簡單介紹這些,下面我們要介紹一個重要的 Ruby 概念。就是
interator (迭代器)。 這個概念遍佈在很多 ruby 代碼中,也是最常見的 ruby way 。正是因
爲 interator ,在 ruby 程序中,你很少會看到循環的使用。 舉個最簡單的例子,如何打印
從 1 到 6 的結果。

在 java 等語言中,我們的實現方法是:
for(int i = 1; i<6;i++) {
System.out.println(i);
}


而在 ruby 中,一切皆爲對象,數字本身就是對象(我們在前面已經介紹過了),數字本身有
它自己的迭代器 times 。那麼讓我們看看它的實現。
6.times {|i| p i }

是不是很簡單。


迭代器的概念很有趣,它是如何在 ruby 中實現的呢。每個函數可以不光帶有參數,還可以 在參數後面帶一個代碼塊。代碼塊在 ruby 中是以 {} 和 do end 來包圍起來的。通常如果 是單行使用 {} ,如果是多行這使用 do end 。這並非強制,只是習慣性用法。


代碼塊和參數並不相同,它和函數的執行可以說是並行的,確切的說是接替進行。如果在函 數內部如何在運行過程中碰到了 yield ,它就會將函數執行過程交給函數附帶的代碼塊來執 行,代碼快執行完了,執行流程轉到函數內部繼續運行。似乎很難理解,以下面這段代碼來 理解可以會容易一些。


def callBlock yield
yield end


callBlock { puts "In the block" }
輸出:

In the block
In the block


CallBlock 函數中只有兩個 yield 語句,它在執行過程中將執行權交給 函數附帶的 block 運行,block 輸出字符串 "In the block" ,這樣最終結果就是輸出兩行 "In the block" 。 在函 數內部使用 yield 還可以帶任意多參數。比如


yield a, b, c

這三個參數對應代碼塊中的三個參數 {|x,y,z| p x y z }

好了, Ruby 就介紹到這裏。下面正式進入正題,介紹一下 Rails 的使用。

 

 

什麼是 rails ?


在寫這個教程的最初,我基本上是在翻譯網上的教程。但是 rails 中包含了太多的程序和概
念,如果只是簡單的介紹,你雖然會很快學會使用 rails ,但是對於它的一些概念瞭解不深。 在這裏我希望更多地介紹一些 rails 所包含的工具,比如 rubygems , webrick 等等。


整個教程是基於ruby的 windows 發行版。Ruby 作爲跨平臺的腳本語言,幾乎在所有的平 臺上都有相應的實現,很多 linux 發行版本都帶有了 ruby安裝文件,而 windows 平臺則需 要從 www.rubyforge.net 上下載 一個 one-click installer 安裝程序。 由於 ruby one-click installer 帶有了 rubygems package manager包,所以就省去了我們很多麻煩。我們只需要一 條命令就可以從網上下載 rails 了(當然安裝 rails 你需要保證你的機器連上 internet )。


簡單介紹一下 rubygems. Rubygems 是最近漸漸在 ruby 社區流行起來的包管理工具。 在 以前,如果你要下載一個 ruby 擴展或者應用程序的話,你需要下載相應的 zip 包,然後 解壓縮,將應用或者擴展安裝到 ruby 對應的目錄中。但是有了新的 rubygems. 所有這些麻 煩都沒有了,你只需要一條命令就可以從遠程服務器上下載相應的包,如果相應的應用包含 其他擴展,rubygems 也會提示你從遠程安裝所依賴的擴展。安裝後 rubygems 會運行相應 的程序生成 rdoc 幫助文檔(類似於 javadoc )。 當然你也可以將軟件包下載到本地運行 rubygems 的本地安裝命令。 有了 rubygems 包管理器, ruby 應用的安裝將變得前所未見 的容易。 統一化的管理帶來的好處就是簡單。現在 ruby 社區的應用都在朝着寫 gems 的 方向發展,很多以前的 RAA 都轉化爲 gems 了, 而 rubygems 也將成爲 ruby 事實上的 包管理器標準了。 記得以前看電影《指環王》的時候記得一句話,那就是 “one ring to rule them all”, 有了 rubygems ,你可以說是 “one gem to rule them all ” 了。

 

安裝 ruby


首先我們看看,如何安裝 windows 版本的 ruby .

最新版本的 One-Click Ruby Installer for Windows 可以從 http://rubyinstaller.rubyforge.org/
上下載。安裝界面如下:

 


安裝沒有什麼特殊之處,只要選擇好安裝目錄,接受默認的設置連續點擊 next 就可以完成。

 

使用 rubygems 安裝 rails


現在我們來看看如何用 rubygems 來安裝 rails. 剛纔我們說過了,因爲 One-Click Ruby
Installer for Windows 已經包含了 rubygems 包管理器,所以我們不在下載安裝 rubygems , 直接利用它來下載 rails.

 

gem 命令包含很多子命令和相應的選項,比如


gem -h/--help – 顯示 rubygem 的幫助
gem -v/--version – 顯示 rubygem 的版本號
gem list –local – 用子命令 list 列出本地安裝的 gems
如圖顯示本機安裝的 gems

 

打開 DOS 命令行窗口,運行如下命令:
gem install rails –remote

這條命令顯式地從遠程服務器上安裝 rails ,你也可以運行 gem install rails 來安裝, gem
會判斷本地是否安裝了rails ,由此來決定是否從遠程安裝 rails.
如圖顯示

 

 

 

你安裝的時間不同,顯示的信息略微有所不同。不同之處在於安裝 rails 所依賴的擴展包有
所不同。一般來說,安裝 rails 需要的包有 rake (這是類似 java ant 的 build 程序), activerecord(rails 依賴的 orm 工具,也就是 MVC 中的 Model 模塊),actionpack (對應的 controller 模塊)。 你可能會問那麼相應的 view 模塊怎麼沒有安裝,因爲 view 模塊已經 在默認的 ruby 安裝中包含了,就是 eruby, 它的作用就是完成對模板文件 .rhtml 的解釋。

 


安裝 mysql 數據庫和管理中心。

 


從 mysql.com 上下載 windows 版本的 mysql 服務器,本文章以 mysql 4.1 版本爲例子(下
載地址爲 http://dev.mysql.com/downloads/mysql/4.1.html).
默認設置安裝 mysql , 在運行到結尾處安裝程序會啓動安裝嚮導,在安裝嚮導中需要設置 安全信息(用戶名和口令)。由於 mysql 從 4.1.7 版本後採用了新的認證算法,這和老版本
的 rails 不兼容,所以網上教程不要求在這裏設置用戶名和口令。但是新版本的 rails 已經 解決了這個問題。本教程暫時不設置用戶名和口令。

 


oreily 網站上發佈的rails 教程中是以 MySQL-Front 爲客戶端程序的。由於這是個商業程序 雖然使用比較方便,但是會遇到過期的問題。所以本教程採用了免費的MySQL Control Center
客戶端程序(mysqlcc-0.9.4-win32),本程序可以從 mysql.com 上下載。安裝界面如下:

 

 


編寫 rails 應用

 

總算到了這激動人心的一步了。
註明:以下示例大量參考了ONLamp.com (http://www.onlamp.com/) 上的 Ruby on rails 教程“Rolling with Ruby on Rails” 原網址: http://www.onlamp.com/lpt/a/5546

 

任務簡介:
我們這裏要用 rails 實現的是一個簡單的網上書籍管理程序 mybook 。 我們所要完成的任務如下:
1:顯示本人所蒐藏的所有書籍
2:新增和編輯相應的書籍
3:將書籍指定不同的類別


在這裏你會看到 rails 框架所展示的前所未有的易用性,整個程序你只需要真正輸入一行代 碼,就可以完成數據庫的 CRUD 操作(增刪改查), 這不僅僅是完成數據庫級別的操作, 連所有相應的默認視圖也都一併完成。 Rails 是我所用過的各種 web 應用框架中最最簡單 的一個,它的開發效率的確遠遠超過了任何一個 java 框架。

 

創建空的 rails 網頁應用程序骨架

 

在 DOS 命令行窗口運行 rails mybook (本程序的工作目錄是 D:railsdoc>)


D:railsdoc>rails mybook create
create app/apis
create app/controllers create app/helpers create app/models
create app/views/layouts create config/environments create components
create db create doc create lib create log
create public/images create public/javascripts create public/stylesheets create script
create test/fixtures create test/functional
create test/mocks/development create test/mocks/test
create test/unit create vendor create Rakefile create README
create CHANGELOG
create app/controllers/application.rb create app/helpers/application_helper.rb create test/test_helper.rb
create config/database.yml create config/routes.rb create public/.htaccess
create config/environment.rb
create config/environments/production.rb create config/environments/development.rb create config/environments/test.rb
create script/console
create script/console_sandbox create script/destroy
create script/generate create script/server create script/runner
create script/benchmarker create script/profiler
create script/breakpointer create public/dispatch.rb create public/dispatch.cgi create public/dispatch.fcgi create public/404.html create public/500.html create public/index.html create public/favicon.ico
create public/javascripts/prototype.js
create doc/README_FOR_APP
create log/server.log create log/production.log
create log/development.log create log/test.log


D:railsdoc>
你可以看到, rails 已經爲你生成了 mybook 應用程序的完整目錄結構。


Rails 不僅僅是一個運行時網絡應用框架,它本身包含了豐富的腳本來幫你完成程序基本骨 架的工作。


運行 rails mybook 後, rails 將生成 mybook 應用程序的默認目錄結構和初始化文件。Rails 開發的方式是: 由 rails 來生成默認的應用程序骨架,你所做的工作就是在默認目錄結構 中編輯文件增加應用程序邏輯就可以了。

 

緊接着我們來測試一下空的應用程序,看看 rails 默認給我們完成了什麼工作。


本程序 的工 作目錄 是 D:railsdoc>, 上面 rails 已經給 我們 生成了 mybook 目錄,進 入 mybook 目錄。運行 ruby scriptserver 。 這條命令是運行 script 目錄下的 server 命令 來啓動 webrick 服務器。


啓動 webrick 服務器如下:

 


打開瀏覽器 ,輸入網址http://127.0.0.1:3000/ 你會看到類似的網頁。

 


暫時不要關閉這個窗口。

 

 


Webrick 簡介:


Ruby 默認已經包含了豐富的軟件,其中 webrick http 服務器就是其中之一。 這個程序包被 用作 rubygem 的默認文檔服務器。這是一個非常簡單的純 ruby 編寫的服務器。如果你掌握了 webrick 你可以用幾行代碼來運行一個 web 服務器。

 

打開編輯器,編寫以下腳本


require "webrick"


httpd = WEBrick::HTTPServer.new(
:DocumentRoot =>Dir::pwd + "/ruby",
:Port => 80
)
trap(:INT){ httpd.shutdown }
httpd.start

然後保存到 c:server.rb 下,雙擊 server.rb , 一個最簡單的 http server 就運行了,它將
c:ruby 目錄作爲服務器文檔根目錄。

 

 

在瀏覽器窗口打開 http://127.0.0.1/


你將會看到 c:/ruby 目錄的內容,我們的 8 行 ruby 代碼就生成了一個簡單 http 服務器。
你不光可以定製文檔根目錄,你還可以象編寫 java servlet 那樣,爲 webrick 編寫 ruby servlet 代碼。具體詳細信息參看 www.webrick.org

 

 

 

 

 


Rails 開發工作的大部分集中在創建和編輯 apps 目錄下的文件。讓我們首先來了解一下這個目
錄下的結構。
Apps 目錄下包含四個主要目錄,它們分別是 Controllers, models, views, helpers
1:Controllers 目錄存放 rails 應用中相應的 controller 類,controller 類處理來自用戶 的 web 請求。

2:views 目錄存放相應的模板文件,模板文件填充數據後,轉換爲 html 格式傳遞給用戶的瀏 覽器。


3:models 目錄存放數據模型類,模型類封裝了數據庫中的數據。很多框架在數據模型層都做 的比較複雜,用過 rails 後,你會發現它非常容易使用。


4:helpers 目錄存放了簡化 Controllers, models, views 使用的幫助類。

 

 

編輯 controller 類


開始使用 Rails 之前,我們需要了解一下 rails 是如何將 controller 類中的方法和 url 映 射到一起的,這對於理解 rails 工作原理很重要。


rails 在生成的 skeleton 框架中包含了一個 scripts 目錄,這個目錄中包含了很多腳本程序, 它們可以幫助我們來簡化很多工作,我們已經使用過了 scriptserver 這個腳本,它是用來啓
動 webrick 服務器的。現在我們看看如何生成默認的 controller 文件


打開新的 DOS 命令行,運行 ruby scriptgenerate controller MyTest


D:railsdocmybookappcontrollers 目錄中將生成一個包含 MyTestController 類定義骨架 的名爲 my_test_controller.rb 的文件

鼠標右鍵點擊此文件,選擇”edit” 打開編輯此文件。

 

 


在瀏覽器中訪問 http://127.0.0.1:3000/My_Test/,

 

 


瀏覽器響應沒有找到對應的 index 方法,不要擔心,這不是什麼大問題,因爲默認生成的
控制器類,不包含任何方法。不過這裏我們瞭解到,如果不輸入任和 url 連接的話,默認 rails 需要在控制器類中找一個 index 的方法。這很容易理解,類似於 apache 服務器中目 錄下面的 index.html 文件一樣。
我們現在編輯這個 MyTestController 類。

 

如圖:

 

 

 

重新刷新剛纔的頁面 http://127.0.0.1:3000/My_Test/ ,你會看到如下結果

 

 


繼續編輯這個控制器類,

 


保存文件後,在瀏覽器中運行 http://127.0.0.1:3000/My_Test/hello

 


這下你瞭解到 rails 是如何將 url 和控制器中的函數做簡單映射的了吧。

這裏需要做一些解釋,在運行 ruby scriptgenerate controller MyTest 的時候, rails 做 了一些默認的假設。MyTest 對應的 controller 文件是 my_test_controller.rb, 文件中控制 器類名是 MyTestController,而 url 映射是 /My_Test/ .


這些默認規定的好處是:我不需要編輯複雜的配置文件,只要對相應的文件做編輯就可以了。我 們只需要關注程序邏輯,而不是其它什麼,這就是 rails 設計原則中的“習慣約定優於配置”。

另外我們也感覺到 ruby 動態語言的好處,這點是 java 所無法辦到的。我們在編輯完 controller 後,重新刷新頁面,就可以使程序生效。對於編譯型的 java 語言來說,不重新編 譯,重新啓動服務器是無法做到這點的。Rails 開發的易用性可見一斑了,要知道啓動和編譯都 是非常耗費時間的,尤其對於那些 EJB 服務器來說更是如此。

 

 

創建 mybook 數據庫

 

1:打開 MySQL Control Center , 新建 mybook 數據庫

 

 


2: 新建數據庫表 books

 


表字段的定義如圖所示

id int(11) 主鍵 title varchar(100) description text buydate date

3: 告訴 rails 如何找 到數據庫信息,打開 D:railsdocmybookconfig 目錄 ,編輯 database.yml 配置文件。 ruby 程序喜歡用 yaml 作爲配置文件,這種做法就象是 java 程 序喜歡用 xml 作配置文件一樣,是傳統習慣了。


新增內容:

YAML 簡介:
很多初次接觸 Ruby 的人可能會對它採用 yaml 文件作爲配置文件感到奇怪。Yaml 庫已經內置在 ruby 發 行版本中,做爲很 “Ruby way”的方式用在各種讀取配置的操作中。希望瞭解 Yaml 格式的人,可以參看 一下 http://www.yaml.org


這裏翻譯一下該網站對 yaml 的解釋:


&<49; YAML 適合人們閱讀
&<49; YAML 適合與腳本語言交流
&<49; YAML 使用宿主語言的內部數據結構
&<49; YAML 擁有一致性的信息模型
&<49; YAML 使基於流式數據的處理成爲可能
&<49; YAML 富於表達和可擴展
&<49; YAML 容易實現

 

yaml 做爲一個可移植的對象序列化方案,可以在不同的 Ruby 進程中將對象以普通文本傳遞,此外也適合
ruby 與那些支持 yaml 的語言之間交換數據用。


如何將 ruby 對象保存到 yaml 文件中.
參考文檔: http://www.ruby-doc.org/core/classes/YAML.html


require ‘yaml’
tree = { :name => ‘ruby’,
:uses => [‘script’,’web’,’testing’,’etc’]
}


File.open(“tree.yaml”,”w”) {|f| YAML.dump(tree,f)}

 

如何在 ruby 程序中讀取 yaml 文件。
require ‘yaml’


tree = YAML.load(File.open(“tree.yaml”)
tree[:uses][1]


輸出結果: “web”


yaml 格式的一個大用途就是用在存儲配置信息,因爲它是純文本格式的,非常適合閱讀,同時又很適合 Ruby 等腳本程序將其讀取到對象中。
下面就是個例子:

 

conf/config.yaml 文件內容如下:


host: 127.0.0.1
prefs:
username: mulder password: trustno1 filename: xfiles


我們可以在 ruby 中這樣使用它
require ‘yaml’
config = YAML.load(File.open(“conf/config.yaml”)) config[“host”] -- 輸出結果 “127.0.0.1” config[“prefs”][“password”] -- 輸出結果 “trustno1”

 

 

 

由於重新定義了數據庫配置,需要重新啓動 webrick 服務器才能讓 rails 找到數據庫配置信
息。
4:在 Mybook 目錄下打開 DOS 命令行窗口, 運行 ruby scriptgenerate model book

 

 

 

rails 生成 Model 類 Book 的骨架文件 book.rb。在這裏 Rails 將數據庫中的 books 表映射
到 Book 類。 這裏 Rails 再次使用了習慣約定,那就是數據庫表以複數形式命名,而與之 對應的 Model 類,使用單數形式。這裏 rails 非常智能,它理解英文的複數規則,會自動
將 person 類和複數形式 people 數據庫表做映射。 打開 book.rb


class Book < ActiveRecord::Base
end

 

 

5:在 Mybook 目錄下打開 DOS 命令行窗口,
運 行 ruby scriptgenerate controller book 生 成 controller 骨 架 文 件
book_controller.rb。

 

 

 

 


編輯 D:railsdocmybookappcontrollers 下的 book_controller.rb

 

好了,魔法正式開場了。到現在我們還沒有編寫一行代碼。如上所示


class BookController < ApplicationController


end
scaffold :book


scaffold :book – 這句是你惟一需要寫的代碼,它生成了數據庫表對應的 CRUD 操作,而且
令人激動的是它生成了對應的視圖模板文件。

我們來測試一下,在瀏覽器中打開 http://127.0.0.1:3000/book/new

 

 

整個數據庫表的登記界面已經爲你做好了,你現在連 html 頁面都沒有打開過,這就是 rails
給我們帶來的神奇之處。我們試着登記一些信息。

 

 

 

 

 

 


你會看到我們已經擁有了 book 表的所有頁面操作,show (顯示錶記錄),edit (編輯表記錄),
destroy(刪除表記錄)。

 

scaffold :book 爲我們完成了所有這一切,scaffold 是一個函數,它接受 :book 作爲參數, 這裏 :book 是一個 symbol ,在 ruby 中, symbol 可以理解爲變量名, 比如一個變量 book
= 1 , 如果直接引用 book ,會得到 1,如果 :book,就指變量名本身。


scaffold :book 會生成 list, show, edit, delete 四個操作,對應表的操作。默認的操作頁面很 平常。如果我們想定製,也很簡單,只要我們自定義自己的四個函數就可以了。
我們重新編輯 book_controller.rb 文件
class BookController < ApplicationController scaffold :book
def list

 

end
end

 

 

刷新瀏覽器頁面

 

 

 

提示說我們缺少模板文件。因爲我們自定義了 list 函數,所以 rails 將不再使用 scaffold 給
我們生成的 list 版本。所以我們必須編寫自己的模板文件。

 

 

當我們用命令 ruby scriptgenerate controller book 生成 controller 文件的時候, rails 同樣在 view 目錄下生成了 book 目錄用於放置我們自己寫的用於 controller 調用顯示的模 板文件。這裏我們需要自己寫一個 list.rhtml


代碼如下:


<html>
<head>
<title>All books</title>
</head>
<body>


<h1>Online Mybook - All books</h1>
<table border="1">
<tr>
<td width="80%"><p align="center"><i><b>book</b></i></td>
<td width="20%"><p align="center"><i><b>Date</b></i></td>
</tr>


<% @books.each do |book| %>
<tr>
<td><%= link_to book.title, :action => "show", :id => book.id %></td>
<td><%= book.buydate %></td>
</tr>
<% end %>
</table>
<p><%= link_to "Create new book", :action => "new" %></p>


</body>
</html>


我們重新編輯 book_controller.rb 文件
class BookController < ApplicationController scaffold :book
def list
@books = Book.find_all


end
end

 

 

 

再次重新刷新頁面

 

 

OK 了,現在我們很容易的定製了列表頁面。
在這裏稍微做一些解釋:


@books = Book.find_all
這條語句告訴 rails ,調用 Book 模型類中的 find_all 函數從數據庫表 books 中把所有記 錄讀出賦值到 @books 實例變量中。接着 rails 尋找 list.rhtml 以生成結果頁面傳遞到瀏覽 器頁面顯示。在 list.rhtml 中


<% @books.each do |book| %>
<tr>
<td><%= link_to book.title, :action => "show", :id => book.id %></td>
<td><%= book.buydate %></td>
</tr>
<% end %>

從 controller 中傳遞過來的 @books 變量調用 each iterator 循環邊歷 @books 中的數據
集。熟悉 asp, jsp 的人對上面的代碼一定不陌生。這裏使用的代碼只不過是嵌入的 ruby 代 碼而已。即使不太瞭解嵌入 ruby 腳本,上面的代碼也很直觀。

 

 

 

 

 


6:創建 categories 數據表 定義如下:

 

 

 

 

 

 

在 D:railsdocmybook 目錄中打開 DOS 命令行,運行下列命令爲 Category 生成模型和控 制器類


ruby scriptgenerate controller Category ruby scriptgenerate model Category

打開 D:railsdocmybookappcontrollers 中自動生成的 category_controller.rb 編輯


class CategoryController < ApplicationController scaffold :category
end

保存後,重新打開瀏覽器窗口,訪問 http://127.0.0.1:3000/category/new

 

添加書籍類別數據

 

 


爲了讓 books 數據表包含類別字段,我們需要新增加一個 category_id 字段,字段定義爲 int
型與 categories 表的 id 字段類型相同。

 

 


打開 Model 目錄中的兩個 model 類文件 book.rb 和 category.rb 進行編輯,各增加一行

book.rb 修改如下:


class Book < ActiveRecord::Base belongs_to :category
end

這行代碼告訴 Rails, 一本書屬於一個類別

category.rb 修改如下:


class Category < ActiveRecord::Base has_many :books
end
這行代碼告訴 Rails, 一個類別可以包含很多本書。 這兩行申明就可以給我們生成在表關係之間導航的各種方法。例如,@book 變量中保存了
一本書的信息,我們想知道它屬於的類別名,我就可以使用代碼 @book.category.name , 再 比如,@category 保存了一個類別,我們想知道這個類別下有多少本書,那麼我們可以通過
@category.books 來獲得。

注意:原來數據庫中的數據應當更新books表的category_id字段

現在我們從新定義 edit 函數,來覆蓋它的 scalffold 版本。
編輯 book_controller.rb 文件
class BookController < ApplicationController scaffold :book
def list
@books = Book.find_all
end
def edit
@book = Book.find(@params["id"])
@categories = Category.find_all


end
end

 


edit 函數中定義的兩行代碼產生兩個實例變量,這兩個變量 @book 和 @categories 將在
edit book 頁面中用到, @book 變量存放我們要編輯的書本對象, id 參數取自網頁的訪問 請求。 @categories 變量存放數據表 categories 中所包含的所有記錄。

 

因爲我們已經從新定義了 edit action ,那麼我們同樣需要自己編寫 edit.rhtml。 和前面 list action 對應 list.rhtml 類似。

打開 D:railsdocmybookappviewsbook 目錄 ,新建一個 edit.rhtml 輸入如下內容


<html>
<head>
<title>Edit book</title>
</head>
<body>
<h1>Edit book</h1>


<form action="../update" method="POST">
<input id="book_id" name="book[id]" size="30"
type="hidden" value="<%= @book.id %>" />
<p><b>Title</b><br>
<input id="book_title" name="book[title]" size="30"
type="text" value="<%= @book.title %>" />
</p>
<p><b>Description</b><br>
<input id="book_description" name="book[description]"
size="30" type="text"
value="<%= @book.description %>" />
</p>
<p><b>Category:</b><br>


<select name="book[category_id]">
<% @categories.each do |category| %>
<option value="<%= category.id %>"
<%= ' selected' if category.id == @book.category.id %>>
<%= category.name %>
</option>
<% end %>
</select></p>

 

<input type="submit" value="Update" />
</form>


<a href="/book/show/<%= @book.id %>"> Show
</a> |
<a href="/book/list"> Back
</a>


</body>
</html>

 

 

注意紅字的內容,我們正是通過編輯 book_controller.rb 文件中的 edit 函數建立的變量
categories 來循環生成“類別”下來菜單內容。


打開瀏覽器,http://127.0.0.1:3000/book/list 點擊任和一條記錄進入編輯頁面,選擇 edit 按 鈕,顯示如下編輯頁面

 


選擇相應類別,點擊 update 按鈕。重新編輯修改現有的兩個記錄,從而在 books 表記錄
中增加類別信息。
我們現在編輯的 list.rhtml 並沒有包含 category 顯示欄目,現在從新加上 從新打開 llist.rhtml ,增加如下紅字顯示的兩行


<html>
<head>
<title>All books</title>
</head>
<body>


<h1>Online Mybook - All books</h1>
<table border="1">
<tr>
<td width="80%"><p align="center"><i><b>書名</b></i></td>
<td width="20%"><p align="center"><i><b>類別</b></i></td>
<td width="20%"><p align="center"><i><b>購買日期</b></i></td>
</tr>


<% @books.each do |book| %>
<tr>
<td><%= link_to book.title, :action => "show", :id => book.id %></td>
<td><%= book.category.name %></td>
<td><%= book.buydate %></td>
</tr>
<% end %>
</table>
<p><%= link_to "Create new book", :action => "new" %></p>


</body>
</html>

從新刷新瀏覽器內容(http://127.0.0.1:3000/book/list

 


我們開始定義的三個任務已經完成。
關於 Ruby on rails 的思考(新增內容)


我是從 thserverside.com 上瞭解到 Ruby on rails 的。oreilly.com 的教程的確對它的推廣起 了很大的作用。我本能地立刻打算翻譯它, csdn 上立刻出來的兩篇介紹性文章讓我打消了 這個念頭,但是它們寫的不夠詳細,從網友的回覆來看,大家對 rails 持懷疑的態度。我覺 得還是應該寫一份更詳細的教程來讓大家認識 Ruby on rails,於是就有了這篇文檔。我希望 把它做成國內最詳細的 Rails“入門”教程,rails 中 ruby 語言的知識點還是很多的。


我是 Ruby 語言的愛好者,但是並不是 Rails 的狂熱分子。我覺得 rails 的一些缺點會影響 大家採用它,有必要在這裏給大家列出來。

1: Rails 畢竟還沒有大型項目的成功案例.
最近出現的個人目標管理網站 www.43things.com 是用 rails 製作的(國內的 www.aimi.cn
是用 asp 技術實現的),相信不久會有更多由 Rails 製作的網站出臺。好的成功案例對一門 語言或技術來說是最好的廣告,從當年 google 對 python 的推廣就能看出來。


2:Rails 是最近剛剛出 來 的框架, 還 不夠成熟 。 Theserverside.com 就有 一篇關於 active record(Rails 內部的 ORM 組件) 和 hibernate ORM特性的比較文章,大家可以參看 http://www.theserverside.com/articles/article.tss?l=RailsHibernate


3:Rails 是用 ruby 開發的,掌握一門新語言對很多人來說是難以接受的。這種情況表現在 兩部分人中,一部分是已經掌握了 java ,c#, c++ 的高級程序員,他們認爲這些語言已經足 夠成熟和完善,沒必要再學習另外一種編程語言。另一部分人是剛剛入門 java, c#, c++ 的 初級程序員,他們還正在努力學習流行的編程語言,更沒精力來了解一種中文資料很少的腳 本語言了。 其實以我個人的感覺來說,一個程序員掌握一門靜態編譯型語言和一門動態腳 本語言是非常必要的。腳本語言對於開發小程序的效率是非常高的,用 ruby 來實現代碼生 成器和文本文件處理的工作遠比 java 要容易的多,實際上我就是在 java 項目中使用自己 編寫的 ruby 工具的。我相信未來也不會出現什麼全能型的語言,而且掌握兩種語言對一個 真正的程序員來說不是那麼困難的事情,而且很必要。


4:ruby 缺少組件的架構。 我覺得未來應用程序框架應該具備兩個特點,那就是:“易用性”和“組件”。從現在的情形 看,Rails 具備了“易用性”的特點,而大多數 Java 框架具備了“組件”的特點。我覺得:
“好的框架的複雜性應該被組件封裝在“黑箱”中,而“易用性”應該體現在組件的使用上”。 所以 Rails 的未來應該向組件上發展,而 Java 框架應該繼續在組件易用性上多做文章,兩 者的趨勢是融合。

我覺得這個文檔引起 Java 程序員的反思要多於實際使用 Rails 的意義。
總結:

 

仔細看看,使用 rails 開發程序,我們並沒有寫很多代碼,對比起其他的 java 框架來說, 它異常的簡單易用。在這裏 rails 給我們充分展示了“習慣約定優於配置”和“編寫少量代 碼”的設計思想,它帶來的好處是顯而易見的。 Ruby on rails 雖然是一個新興的框架,盡 管還不夠成熟,但是它在 java 社區引起的騷動足以讓我們重新審視 java 世界的一些編程 思路,rails 和 ruby 在很多地方借鑑了 java 的思想,而它們自身有保持了自己特有的優勢。 相信會有越來越多的人採用 rails 來開發網絡程序的。如果你是最新安裝 rails 你會發現它 依賴的模塊中又新增加了 actionwebservice 模塊,相信 rails 會繼續給我們帶來驚喜的。

 

作者 Eiffel Qiu
Email: [email protected]
WWW: http://www.koalant.com

 

 

參考資源:(新增內容)


Ruby 網站資源:


ruby 官方網站: http://www.ruby-lang.org
ruby doc 官方網站:http://www.ruby-doc.org
rubyonrails 官方網站: http://www.rubyonrails.org
programming ruby 在 線 版 ( Ruby 學 習 的 “ 聖 經 ” ) :
http://www.rubycentral.com/book/index.html
Ruby 開源項目的主站:http://rubyforge.org/ , rails, rake, rubygem, one click installer 都在此 下載。
Webrick 純 Ruby服務器: http://www.webrick.org
Yaml 官方網站: http://www.yaml.org
ONLamp.com ROR 教程:(http://www.onlamp.com/) http://www.onlamp.com/lpt/a/5546
注:本文示例大量參考了此教程。 

發佈了35 篇原創文章 · 獲贊 0 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章