前言
今天來探討一下find及where的差異,這邊建立了一個Model Todo 來做測試
實際測試
單筆比較
Todo.find(1)
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]#=> RETURN: {id: 1, title: "first"}
Todo.where(id: 1)
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? [["id", 1]]#=> RETURN: [{id: 1, title: "first"}]
Todo.where(id: 1).take
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]#=> RETURN: {id: 1, title: "first"}
可以看出find單筆抓出來的是object,而where是array,但是加上take也可以取出object
多筆比較
Todo.find(1,2)
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" IN (1, 2)
#=> RETURN: [{id: 1, title: "first"}, {id: 2, title: "second"}]
Todo.where(id: [1,2])
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" IN (1, 2)
#=> RETURN: [{id: 1, title: "first"}, {id: 2, title: "second"}]
可以看出多筆都會取得array
無資料比較
Todo.find(3)
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
#=> RETURN: ActiveRecord::RecordNotFound: Couldn't find Todo with 'id'=3
Todo.where(id: 3)
#=> SQL: SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? [["id", 3]]
#=> RETURN: []
可以看出若find找不到,就會直接報錯,而where是回傳空array
結論
find
依照你輸入的是單筆還是多筆,決定回傳值為單一object或array
查不到資料會報錯
where
不管在任何情況下,皆是以array方式回傳
查不到資料,回傳空array
使用上建議
當你確定只找一筆資料時,使用find,可以比where少打一些字當不確定是單筆或多筆時,使用where,可以確保取出來都是array,後續資料才好處理
備註實際上where回傳不是array,而是使用ActiveRecord::Relation建立的object,但它類似array,可以以array來理解
參考
http://stackoverflow.com/questions/9574659/rails-where-vs-find