人們常常說,用rails久了SQL會退步
因為Active Record實在太好用了
都不用自己寫sql查詢
這個月剛好寫rails滿一年,我深深覺得此言不假
以前我是java工程師,搭配的資料庫SQL語言是IBM infomix
那個時候我還常常自豪可以將複雜的商業邏輯
用長達10行左右的SQL來實作,現在卻幾乎忘光光了
只知道 where from ...
這就是rails神奇之處,讓你再也不用煩惱如何組SQL
但前提當然是要能夠靈活運用Finder
雖然Finder有數十種,但最常用到的大概就那幾種
這篇就介紹一些冷門的Finder,或許在特殊情境下
會有使用上的機會
跟first或last很像,但是沒有排序
後面加參數可以指定要取幾個,例如
Dog.take 3
姑且可以當作亂數取用視之
顧名思義,加上這個找回的物件
沒辦法編輯或修改
當找不到物件時,就新增一筆
類似的還有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可以看出,他會先搜尋有沒有符合名稱的物件,
如果沒有,就把條件作為值新增一筆
用來查詢一個或多個欄位
比較不同的地方是,他回傳的是陣列而不是Active Record
例如
Dog.pluck :id
=> [1, 2]
ids算是特製版的pluck
但是他只會回傳id陣列
所以剛剛上面的例子也可以改寫如下
Dog.ids
=> [1, 2]
如果只是想知道物件存不存在,之後沒有要取用
可以改用這個方法,
Dog.find(1).present?
=> true
Dog.exists?(1)
=> true
#兩者相等
條件也可以是一組陣列,例如
Dog.exists?(id: [1,2,3])
# or
Dog.exists?(name: ['John', 'Sergei'])
回傳指定欄位的平均值,浮點數
Dog.average("age")
Dog.average(:age)
兩種寫法都可以,以下也都一樣
欄位的最小值
Dog.minimum(:age)
欄位的最大值
Dog.maximum(:age)
欄位的合計
Dog.sum(:age)