iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 16
0

人們常常說,用rails久了SQL會退步
因為Active Record實在太好用了
都不用自己寫sql查詢
這個月剛好寫rails滿一年,我深深覺得此言不假
以前我是java工程師,搭配的資料庫SQL語言是IBM infomix
那個時候我還常常自豪可以將複雜的商業邏輯
用長達10行左右的SQL來實作,現在卻幾乎忘光光了
只知道 where from ...
這就是rails神奇之處,讓你再也不用煩惱如何組SQL
但前提當然是要能夠靈活運用Finder

雖然Finder有數十種,但最常用到的大概就那幾種
這篇就介紹一些冷門的Finder,或許在特殊情境下
會有使用上的機會

take

跟first或last很像,但是沒有排序
後面加參數可以指定要取幾個,例如

Dog.take 3

姑且可以當作亂數取用視之

readonly

顧名思義,加上這個找回的物件
沒辦法編輯或修改

find_or_create_by

當找不到物件時,就新增一筆
類似的還有find_or_initialize_by
差別在找不到會new一個物件,但尚未存入資料庫

> Dog.find_or_create_by name: "hahaha"
  Dog Load (0.2ms)  SELECT  "animals".* FROM "animals" WHERE "animals"."type" IN ('Dog') AND "animals"."name" = ? LIMIT 1  [["name", "hahaha"]]
   (0.0ms)  begin transaction
  SQL (0.6ms)  INSERT INTO "animals" ("type", "name", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["type", "Dog"], ["name", "hahaha"], ["created_at", "2016-12-21 15:30:38.894083"], ["updated_at", "2016-12-21 15:30:38.894083"]]
   (0.7ms)  commit transaction
 => #<Dog id: 2, name: "hahaha", type: "Dog", created_at: "2016-12-21 15:30:38", updated_at: "2016-12-21 15:30:38"> 

由SQL可以看出,他會先搜尋有沒有符合名稱的物件,
如果沒有,就把條件作為值新增一筆

pluck

用來查詢一個或多個欄位
比較不同的地方是,他回傳的是陣列而不是Active Record
例如

Dog.pluck :id
=> [1, 2]

ids

ids算是特製版的pluck
但是他只會回傳id陣列
所以剛剛上面的例子也可以改寫如下

Dog.ids
=> [1, 2]

exists?

如果只是想知道物件存不存在,之後沒有要取用
可以改用這個方法,

Dog.find(1).present?
=> true
Dog.exists?(1)
=> true
#兩者相等

條件也可以是一組陣列,例如

Dog.exists?(id: [1,2,3])
# or
Dog.exists?(name: ['John', 'Sergei'])

average

回傳指定欄位的平均值,浮點數

Dog.average("age")
Dog.average(:age)

兩種寫法都可以,以下也都一樣

minimum

欄位的最小值

Dog.minimum(:age)

maximum

欄位的最大值

Dog.maximum(:age)

sum

欄位的合計

Dog.sum(:age)

上一篇
淺談validation -- 資料的守門人
下一篇
length , size and count
系列文
Ruby礦工的Rails地圖30

尚未有邦友留言

立即登入留言