大貓共和國

Meow

Hirb-unicode: 解決hirb中全形文字排列的問題

hirb是可以改變irb資料輸出方式改變的gem,其最常應用的場合就是將rails中ActiveModel的資料轉為表格。但中文網站的開發者,應該常常會碰到表格排列歪掉的問題。

使用hirb前:

(真是幾乎無法閱讀)

使用hirb後:

好多了,但是表格歪掉看起來還是很討厭。

其實表格歪掉是由於hirb無法正確計算全型字元的寬度。於是我就包了hirb-unicode這個plugin,以解決這個問題。使用hirb-unicode後:

安裝hirb-unicode

在shell下執行:

$ gem i hirb-unicode

使用hirb-unicode

如果是在irb中使用

gem 'hirb-unicode'
require 'hirb-unicode'

即可自動載入hirb及hirb-unicode,並自動修正unicode排列的問題。

若在bundler的環境下使用(如Rails 3),請在Gemfile中加入

gem 'hirb-unicode'

以便載入gem。(或者用RichRC載入也可以喔)

然後在可以在.irbrc中或直接在irb進行require的動作:

require 'hirb-unicode'

Misc

其實hirb-unicode的源碼不到30行,利用unicode-display_width gem計算長度,再包裝一下切字串的method,其實一下就做完了。原本是想簡單的上個patch到hirb,但作者希望不要增加hirb的dependency,想要將這個功能包成另外的plugin,於是花了很多天往返討論。

Anyway,終於把這個功能包出去了。Happy coding!!

RichRC: 在Rails3 Console中輕鬆使用hirb及wirble的懶人包

開發rails應用時,或多或少會需要在console下進行一些操作。但內建的console其實功能有限,於是就有人寫了一些gems來擴充的irb功能。如hirb可以將資料表格化,而wirble提供了著色、自動完成等功能。

在rails 2中,要使用這些gems提供的擴充功能,只要簡單地在irb下載入gems就可以了。但rails 3使用了bundler管理gems,必需在Gemfile中先加入要使用的gems才可以使用。但修改Gemfile會造成一些問題:這些gems的設定該commit回版本控制系統嗎?我認為不應該,每位開發者可能有自己的偏好設定。另外,使用者可能是clone其他開發源碼的專案,而無法commit東西回去。然而,當有其他人修改Gemfile時,可能會造成conflict需要處理。

對於這個問題,感謝xdite的文章「在 Rails3 上使用漂亮的 console」,指出了可以在bundler.setup執行前搶先載入額外的gems,避過修改Gemfile的問題。文中的做法每要在一個rails app中執行console時,需要修改development.rb, boot.rb, console/rails其中兩個檔案,還是要費些工夫。對於常常clone project下來survey的人來說,這點可能尤其麻煩。

有沒有可能避過這些修改檔案的問題呢?「懶惰的工程師需要勤奮的發明工具」,為了懶得每次修改檔案,我動手寫了一個客製化Rails 3 console的工具:RichRC

安裝

在shell下輸入:

$ gem install richrc hirb wirble

P.S. 雖然RichRC預設載入hirb及wirble,但RichRC其實不相依於hirb及wirble這兩個gems。請參看「客製化」一節。

執行

$ cd railsapp
$ richrc

就這樣,不用修改任何檔案,只要將rails console的指令改為richrc即可。richrc預設會執行下列動作:

  • 載入並啟動wirble
  • 載入並啟動hirb
  • 設定ActiveRecord的log顯示於console中

不用修改任何檔案,三個願望一次滿足。

客製化

雖然本文的標題為「RichRC: 在Rails3中輕鬆使用hirb及wirble的懶人包」,但RichRC其實可以任意客製化Rails 3 console載入時額外運行的程式。

RichRC的原理,其實是在「bundler.setup執行前」及「application載入後」執行特定的程式碼。RichRC會讀取一個設定檔,再依設定檔中的邏輯執行初始化的動作。RichRC啟動時,會試圖依下列順序載入設定檔:

  1. 當前目錄下的.richrc
  2. 使用者家目錄下的.richrc
  3. gem中的預設設定

目前gem中的預設設定就如上一節所述:載入hirb及wirble,並設定ActiveRecord的logger。要執行客製化,可以在在console下執行:

$ richrc customize

即可將預設的設定檔複置到./.richrc。接下來就可以修改並加入您想要的gems及設定,前文中有提到,RichRC並不相依於hirb及wirble,如果你不想要這些gems的話,可以將它們拿掉。以下是預設的.richrc:

before(:setup_bundler) do
  # You can load extra gems here.
  require 'irb'

  begin
    gem 'wirble'
    require 'wirble'
    Wirble.init
    Wirble.colorize
  rescue LoadError
    puts "Failed to load wirble"
  end

  begin
    gem 'hirb'
    require 'hirb'
    Hirb.enable
  rescue LoadError
    puts "Failed to load hirb"
  end
end

after(:load_application) do
  ActiveRecord::Base.logger = Logger.new(STDOUT)
end

注意:只有在before(:setup_bundler)中,才可以載入額外的gems。另外,在after(:load_application)後,rails的環境才被載入完成,才可以去設定ActiveRecord的logger(您亦可在此對rails其他元件做設定)。

備註

注意:在.richrc引入與Gemfile中的gems(及他們所相依的gems)衝突的話,可能會造成問題。

RichRC以MIT License開放源碼,源碼位於github,有問題歡迎回報。

Rails3, Mongoid, Devise, Heroku, MongoHQ筆記

最近在看一些NoSQL的東西,於是想以MongoDB進行一些實作的練習。這篇文章是我在練習過程中,環境設定的筆記。

Installing Rails 3

請看我的上一篇文章

Installing MongoDB

我的開發環境是Ubuntu和Windows(在家用Ubuntu、出外用Windows,所以試了兩個環境)。Linux的話,個人建議不要用package system(apt/yum)的MongoDB。首先,絕對不要apt-get install mongodb。我一開始練習MongoDB時,是用apt-get裝的,會抓到一個舊到爆炸(1.4.4)的stable版本,這個版本mongo console client打錯指令還會crash(這是stable版嗎?)。

如果一定要用package的話可以考慮apt-get install mongodb-unstable或apt-get install mongodb-snapshot。但我是直接去官網抓build好的版本,再sudo copy到/usr/bin就好了。

MongoDB Object Mapper: Mongoid

Mongo的Ruby Object Mapper有很多種,可以參考官網上的列表。我選用Mongoid的原因有二:

  • Mongoid的官網做的還滿有模有樣的,看樣子應該有認真維護 XD
  • Devise認證機制內建支援Mongoid

安裝照著官方installation文件做就好了:

  gem i mongoid –pre
  gem i bson_ext

如果是Windows系統的話,mongo gem需要build一些native code,所以推薦裝RubyDevKit,裝完就可以順利的安裝mongo相關gems。

Mongoid使用上非常的簡單,Mongoid蓋掉了ActiveRecord的generators。要快速建出一個能動的環境,在設定好gems後只需要:

  rails g mongoid:config
  rails g scaffold article title:string content:string

只要mongod開著,這樣就可以動了,不用做data migration。唯一會踩到的雷可能是用了舊版的mongodb,所以就如前面提到的,請不要apt-get install。

Authentication: Devise

Devise是一套不錯的rails認證機制,而且內建對Mongoid的支援 一樣照著官方文件做就能動,整合非常簡單。安裝:

  gem i devise

整合進app:

  rails generate devise:install
  rails generate devise User

接下來只要在view裡把link接一接就好。如果原本就用過devise,基本上用ActiveRecord或Mongoid沒啥差別。要速查link path helpers的話可以用rake routes。

唯一要注意的地方是要記得自己打index,我原本以為Model中的

  devise :database_authenticatable, :registerable #……

這行,會自動在Mongoid Model上加上index。但rake db:mobgoid:create_indexes後,User collection上還是沒有任何index,所以要自己在Model上加:

  index :email, :unique => true

然後再執行一次rake db:mongoid:create_indexes,把index打上去。

另外,有人做了Rails3+Mongoid+Devise的整合包。但Devise和Mongoid的整合實在太簡單了,不彷自己做一遍,也比較容易了解細節。

Deployment Environment: Heroku & MongoHQ

Heroku是一個雲端的Rails Hosting Platform,其使用方式應該很多文章介紹過了,這裡就不多廢話。基本上注冊好heroku帳號後,在rails app路徑下:

  heroku create appname
  git push heroku master

就可以把app deploy上去。

MongoHQ是一個雲端的MongoDB Hosting服務,提供了免費(16MB Limit)及付費的MongoDB空間。由於Heroku與MongoHQ有合作,並將MongoHQ做成了Heroku的一個addon,所以整合特別簡單。這裡是官方文件,只要下一行指令:

  heroku addons:add mongohq:free

heroku就會自動向MongoHQ註冊一個資料庫,並設定rails的環境變數。注意官方文件有個地方沒講的很清楚,在config/mongoid.yml中,多加上mongohq的設定:

  production: 
    uri: <%= ENV['MONGOHQ_URL'] %>

設定好後,MongoID就可以吃到MongoHQ的環境變數,並正確地建立資料庫連線。

順便列一下Heroku合作的資料庫中,免費方案的比較:

  • Heroku內建Database: 5MB (Postgre SQL)
  • Redis To Go: 5MB (Redis)
  • MongoHQ: 16MB (MongoDB)
  • Cloudant: 100MB, 500k requrest per month (CouchDB)

開發筆記待續…

再度考慮搬家

最近應該比較有閒寫心得了,又開始考慮搬Blog的可能性。其實一年前就murmur過這件事了。如果要搬的話,應該就是搬到自己架的Wordpress吧。主要的原因還是這些:

  • 貼code:Bloggger貼code縮排好像還是有機會跑掉。我真的不喜歡一天倒晚embed gist,然後python&haskell縮排跑掉真的很杯具。另外是Wordpress有儲存文章revision的功能,code不小心貼爛還可以回退,而Blogger就沒招了,只能從原本的code從貼一次。
  • 貼數學式:雖然有好幾個方法可以在Blogger上貼數學式(先自己用tex轉圖、用Google Graph API…),可是我都嫌不太方便。我還是較喜歡直接在文章中打類似tex的控製碼。Wordpress有一些plugin可以做到這一點。MathML是一個理想的解法,但目前只有Firefox有較完整的支援,而在Chrome慘不忍睹。
有人有什麼好建議嗎?