Active Record Query Interface part2

Posted by Anthony Chao on 2019-10-05

今天繼續來看看昨天沒看完的部分!

Active Record 搜尋的條件

  • 純字串

我們在搜尋時,可以直接在條件使用字串

1
Client.where("orders_count = '2'")

這個例子會抓出 order_count 是 2 的所有 customer 集合

  • Array Conditions (字串搜尋多條件)

除了使用字串之外,可以使用陣列的方式,陣列的第一個值放字串,其中有幾個問號,後面就要有幾個相對應的值
或者像是下面的第三個範例較為複雜,雖然是以陣列的方式呈現,但抓的值在後面以 Hash 呈現

1
2
3
4
5
6
Client.where("orders_count = ?", params[:orders])

Client.where("orders_count = ? AND locked = ?", params[:orders], false)

Client.where("created_at >= :start_date AND created_at <= :end_date",
{start_date: params[:start_date], end_date: params[:end_date]})
  • Hash conditions

使用 Hash 方式尋找應該是最常見的方式

1
Client.where(locked: true)

然後如果要同時找某個 key 符合多個條件可以使用陣列

1
Client.where(orders_count: [1,3,5])

使用 Hash 條件搜尋還可以包括範圍

1
Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)

選擇特定欄位

在前面的搜尋中,我們拿到的資料都是全部的欄位,如果只想要篩選特定欄位,可以使用 select 這個方法

1
2
3
Client.select(:viewable_by, :locked)
# OR
Client.select("viewable_by, locked")

Limit and Offset

limit 用來限制拿出來的資料有多少筆, offset 用來表示要從哪一比資料開始算起

1
Client.limit(5).offset(30)

這個例子就是從第 31 筆開始拿 5 筆資料出來,一般來說這兩個方法最常用在分頁的時候


Eager Loading Associations

Eager loading 的機制主要是讓搜尋資料庫的時候,可以盡量減少搜尋次數,我們看看下面的例子

1
2
3
4
5
clients = Client.limit(10)

clients.each do |client|
puts client.address.postcode
end

這個例子裡面,第一次搜尋是抓出 client 前 10 筆資料,後面還有 10 次搜尋是找出每個 client 的 address,所以總共進行了 11 次搜尋,這就是 N + 1 問題

我們可以使用 includes 這個方法改寫上面的例子

1
2
3
4
5
clients = Client.includes(:address).limit(10)

clients.each do |client|
puts client.address.postcode
end

如此一來就只會進行兩次搜尋!

那如果是比較複雜的結構呢?

1
Category.includes(articles: [{ comments: :guest }, :tags]).find(1)

這個例子會拿到 id 是 1 的 Category 資料,另外也去讀取跟他有關的文章,還有跟這些文章有關的 comments / tags,還有每個 comment 的 guest 關聯

那今天的文章就寫到這裡啦!

參考資料:

Rails Guide





prevent_hack