Find Randomly Redux

by winson, 6 months ago.

去年寫過隨機挑一筆資料的作法,現在看來其實還有很多可以改進之處。

一、直接寫成Something.random並不是很漂亮的作法,寫成Something.find :random才是符合Rails慣例的作法。

二、部份語法當時看起來簡單,現在則感覺累贅,牽扯到例外處理實在有點麻煩。但是,在實務上,我們也必須處理因為資料被刪除而跳號的情形。


  • Posted in ActiveRecord, on Thursday, January 03, 2008, at 01:50 AM.

Homebrew Immutable Attribute

by winson, 7 months ago.

最近寫點小程式,客戶拜託我其中某個table不要用Rails內建的key,這不是新增一個key就好的問題,而是要用指定的格式當key。

好,從設計的角度來看,格式如何先不管,這個key的值除了生成的那一刻之外,往後都不可隨意變更,不只從view無法變更,甚至要防止程式不小心修改到,這才有資格作為一個key。

先看Rails是否內建防止某個欄位遭到修改的保護機制。這時候,第一個想到的自然是attr_protected:


  • Posted in ActiveRecord, on Saturday, November 24, 2007, at 07:38 PM.

RecordNotFound Exception

by winson, about 1 year ago.

我最近聽過對於Ruby/Rails最有趣的評論是: Ruby/Rails除了簡潔之外,看不出還有什麼優點。

好吧,那就捲起袖子從最簡潔、最可愛的Dynamic Finder以及衍伸的例外處理來看好了。

因為Dynamic Finder實在是太可愛了,所以無處不在,例如:

# Very simple example

def show
  @bug = Bug.find(params[:id])
  @page_title = "About this bug" 
end
這段程式看起來不錯,實則不然,萬一找不到蟲,那怎麼辦呢?這有幾種處理方式:


  • Posted in ActiveRecord, on Monday, June 04, 2007, at 09:26 AM.

Find randomly

by winson, about 1 year ago.

隨機挑資料庫某一筆資料的方式大概有這兩種:

def self.random
  # find(rand count) rescue ActiveRecord::RecordNotFound random
  find(:first)[rand count]
end
第一種先隨機挑,找不到拋出例外再去Rescue例外並挑下一筆,等於跑一個遞迴;第二種是先把全部挑出來,再利用ActiveRecord傳回陣列的特性,從陣列隨機挑一筆。

除非運氣太差,要不很顯然第一種方式快;但第二種語法比較精簡。我個人比較喜歡第二種精簡的方式。

要注意呼叫rand傳回的亂數是從0開始,但資料庫的ID沒有特別設定都是從1開始,第一種方式改成這樣:

find(rand(count) + 1) rescue ActiveRecord::RecordNotFound random
可以保證不會挑到第0筆而再跑一次;但無論如何,就算多跳幾次也應該比第二種方式快,所以加不加1無所謂。

無論採用哪種方式,ActiveRecord都是一種看起來簡單,卻蘊含豐富的變化資料封裝處理,非常討人喜歡啊。


  • Posted in ActiveRecord, on Friday, May 11, 2007, at 11:10 PM.