Find Randomly Redux

by winson, 6 months ago.

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

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

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

個人覺得最佳解是這樣子的:

def self.find(*args)
  scope = args.first
  if scope.to_s == "random" 
    super :first, :offset => (rand count).to_i
  elsif scope.to_s == "public" 
    # blah, blah...
  else
    super
  end
end
為什麼呢?直接抓取資料總筆數作為隨機變數的種子,並運用offset跳到那一筆,既簡單也不用處理例外。也有人把關鍵的那一行寫成這樣:
super :first, :order => "rand()"
這無疑是去呼叫資料庫本身的函數,語法也很簡單沒錯,但總令人覺得不舒服。

我個人的習慣是盡量避免在程式裡頭赤裸裸地寫SQL語法或運用資料庫函數,一來程式沒人看得懂,難以維護;二來會綁死在某個資料庫平台上造成將來系統移植的困難。

無論如何,深入思考以及隨時進行Refactoring,有一天總會想出最好的作法。