← 上一章:類別(Class)與模組(Module) 下一章:Model、View、Controller 三分天下 →
使用套件(Gem)讓開發更有效率
在開放原始碼的世界,有非常多厲害開發者願意無私的貢獻程式碼,而這些程式碼大多會打包成好用的套件,在 Ruby 的世界,我們稱它為 Gem。所有 Gem 的詳細資訊,都可在 RubyGems 網站上找得到:
安裝套件
在 Ruby 要安裝套件相當簡單,只要 gem install
指令加上套件的名字,敲完按下 Enter 鍵,就自動會從網路下載套件、安裝套件,一氣呵成。例如我想安裝一個名為 takami
的套件:
$ gem install takami
Fetching: takami-0.0.1.gem (100%)
Successfully installed takami-0.0.1
Parsing documentation for takami-0.0.1
Installing ri documentation for takami-0.0.1
Done installing documentation for takami after 0 seconds
1 gem installed
如果該套件又需要套件,它也會一併下載、安裝。這個 takami
是我自己寫的 Gem,裡面沒有任何功能,僅是上課時教同學們怎麼把程式碼打包成 Gem 的範例,所以可安心安裝!(咦?!)
所以我說那個套件呢?
安裝 Gem 很簡單,但安裝好了的那些檔案放哪去了?執行 gem env
可列出目前在這台電腦的設定:
$ gem env
RubyGems Environment:
- RUBYGEMS VERSION: 2.6.11
- RUBY VERSION: 2.4.1 (2017-03-22 patchlevel 111) [x86_64-darwin16]
- INSTALLATION DIRECTORY: /Users/eddie/.rvm/gems/ruby-2.4.1
- USER INSTALLATION DIRECTORY: /Users/eddie/.gem/ruby/2.4.0
- RUBY EXECUTABLE: /Users/eddie/.rvm/rubies/ruby-2.4.1/bin/ruby
- EXECUTABLE DIRECTORY: /Users/eddie/.rvm/gems/ruby-2.4.1/bin
- SPEC CACHE DIRECTORY: /Users/eddie/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /Users/eddie/.rvm/rubies/ruby-2.4.1/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-darwin-16
... 略 ...
那個 INSTALLATION DIRECTORY
就是 Gem 安裝的地方,裡面應該就可以找到剛剛安裝的 takami
套件了。因為我是使用 RVM,所以 Gem 的安裝路徑會在 .rvm 目錄裡。
使用 Gem
Gem 裝好了要怎麼使用呢?剛好趁這個機會介紹一個我很喜歡的 Gem:Faker。這個套件可以快速的產生很多種的看起來像真的「假資料」。
安裝套件:
$ gem install faker
安裝完成之後,開 Ruby 內附的互動小工具 irb
來試玩一下:
$ irb
# 先 require 這個套件
>> require 'faker'
=> true
# 產生假的 Email
>> Faker::Internet.email
=> "[email protected]"
>> Faker::Internet.email
=> "[email protected]"
# 連權利遊戲(Game of Thrones)跟寶可夢(Pokemon)的假資料都有
>> Faker::GameOfThrones.character
=> "Ned Stark"
>> Faker::GameOfThrones.character
=> "Stannis Baratheon"
>> Faker::Pokemon.name
=> "Pikachu"
做測試的時候用這個 Gem 來產生假資料相當方便!
在 Rails 專案裡使用 Gem
如果要在 Rails 專案中使用 Gem,需要把要使用的 Gem 標註在專案目錄下的 Gemfile
。打開 Gemfile
,大概會長得像這樣:
source 'https://rubygems.org'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
"https://github.com/#{repo_name}.git"
end
gem 'rails', '~> 5.1.0.rc1'
gem 'sqlite3'
gem 'puma', '~> 3.7'
gem 'sass-rails', github: "rails/sass-rails"
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'capybara', '~> 2.13.0'
gem 'selenium-webdriver'
end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
在這個檔案裡,你可以看到有些 Gem 的後面有加註版本號碼,有的沒有,這分別代表不同的意思:
沒加註版號
先從最簡單的來看。當後面沒有加註版本號碼的時候,像這樣:
gem 'sqlite3'
gem 'jquery-rails'
這樣的寫法將會在安裝的時候選用「最新的穩定(stable)版本」,要注意這裡的重點是「穩定」而不是「最新」。以 Rails 來說,假設最新的版本是 5.0.2 beta 4,但最新的「穩定」版本是 5.0.1 版,當沒有加註版本號的時候,它會選擇安裝 5.0.1 版本。
加註明確版號
例如像這樣:
gem "rails", "5.0.1"
這相當明顯,意思就是說「我要安裝 rails 5.0.1 版」,這應該就不需要特別解釋了。
大於、小於版號
gem 'uglifier', '>= 1.3.0'
我想這個用猜就猜得出來,就是要安裝大於或等於 1.3.0 版本。如果是這樣:
gem 'rails', '>= 5.0.0.beta4', '< 5.1'
則是會選用在 5.0.0.beta4 跟 5.1 之間的版本。
差不多…
gem 'coffee-rails', '~> 4.1.0'
這是指會選用 4.1.0 以上,但 4.2 以下(不包括 4.2)的最新版本。
為什麼這麼麻煩?舉個例子來說,例如版本號 4.2.6
,4
、2
、6
三個數字分別代表主要版號(Major)、次要版號(Minor)以及修訂版號(Patch),分別表示:
- 主要版號:功能大改,公開的 API 做了不少修正,通常沒辦法向下相容。
- 次要版號:加了某些新功能,但不影響其它功能,通常向下相容。
- 修訂版號:對現有的功能做了小幅度的修正,通常可向下相容。
這是個不成文的規定(語義化版本),雖然沒有強制,但幾乎大部份的 Gem 作者都會依照這個規範。這個 ~>
的「差不多」寫法,可以確保不會因為套件昇級而把原本正常運作的系統弄壞了。
使用 Gem 來加速開發
介紹完了 Gemfile 裡的內容,接下讓我們利用現有的 Gem 來加速開發,舉個例子來說:
這個頁面的資料太多了,如果我想做分頁效果,每頁只想呈現 5 筆資料,通常你就得自己算每頁幾筆、現在是第幾頁、總共有幾頁這些數字(我數學不好,很不擅長算這種)。有位好心又很厲害的大大做了一個專門計算分頁的套件稱為 Kaminari,可以很輕鬆的完成這件事:
Step 1: 安裝套件
打開 Gemfile
,加上這行:
gem 'kaminari'
重要:更新 Gemfile 檔案內容後,別忘了要到該專案目錄底下執行
bundle install
指令,確保所有套件都有正常安裝。
Step 2: 修改程式碼
打開專案的 app/controllers/posts_controller.rb
檔案,把原來在 index
方法的 Post.all
做一些調整:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
@posts = Post.includes(:user).page(params[:page]).per(5)
end
... [略] ...
end
page
方法,是 Kaminari 這個套件專門拿來做分頁的方法,後面的 per(5)
就是「每頁有 5 筆資料」的意思。重新整理一下瀏覽器,應該會看到只剩 5 筆了:
(如果發生 page 方法找不到之類的錯誤訊息,重新啟動 Rails Server 之後就正常了)
但這樣還不夠,在畫面上好像還少了「上一頁」、「下一頁」的功能!沒關係,這個套件也幫你做好了。打開檔案 app/views/posts/index.html.erb
,找一個你想要放分頁的地方:
<p id="notice"><%= notice %></p>
<h1>Posts</h1>
<table>
<thead>
...[略]...
</tbody>
</table>
<br>
<%= paginate @posts %>
<br>
<%= link_to 'New Post', new_post_path %>
那行 <%= paginate @posts %>
會幫你把分頁器做出來。重新整理一下畫面:
就這樣,寫沒幾行程式碼就把分頁功能做完了!
小結
善用現有的套件可以大幅的縮短開發時程。這些 Gem 的作者通常很愛現(稱讚意味),他們大多會在說明文件裡詳細介紹這個套件怎麼用(怕你不會用),所以,使用套件前應詳閱公開說明書(README),如果有任何問題,也都歡迎留 issue 給作者們,通常很快就會被解答。
另外,有兩個網站推薦給大家參考:
這兩個網站的影片都有介紹怎麼使用 Gem,其中雖然 RailsCasts 網站已停止更新,但網站上的內容仍非常有參考價值。
Comments