2017-07-26 46 views
0

我有以下型號:添加包括參數渲染方法不能解決N + 1查詢

class Request < ApplicationRecord 
    belongs_to :contact 
    belongs_to :hub_post 
end 

class Contact < ApplicationRecord 
    has_many :requests 
    has_many :likes 
end 

class Like < ApplicationRecord 
    belongs_to :hub_post 
    belongs_to :contact 
end 

class HubPost < ApplicationRecord 
    has_many :requests 
    has_many :likes 
end 

在我HubPostSerializer,我有以下方法:

def liked_by_current_contact 
    scope.present? && object.likes.where(contact_id: scope.id).present? 
end 

在我RequestsController我抓住他們的hub_postslikes請求,然後返回一個JSON響應(我使用active_model_serializers 0.10.4與:json適配器),如下所示:

requests = current_contact.requests.includes(hub_post: [:contact]) 

# More controller code here 

respond_to do |format| 
    format.json { render json: requests, each_serializer: PortalRequestSerializer, scope: current_contact } 
end 

這當然是一個明顯的N + 1問題(子彈寶石出人意料地看起來並沒有出現)。查看日誌時,我可以看到每個hub_post的SELECT語句。現在,我已經試過,包括likes像這樣:

requests = current_contact.requests.includes(hub_post: [:contact, :likes]) 
requests = current_contact.requests.includes(hub_post: [contact: [:likes]]) 

有趣的是,Bullet寶石不會在N + 1的回暖,但Scout一樣。

我也嘗試添加一個include參數我渲染方法,按照documentation,像這樣:

respond_to do |format| 
    format.json { render json: requests, include: 'hub_posts,hub_posts.likes', each_serializer: PortalRequestSerializer, scope: current_contact } 
end 

我使用單級和多級通配符,像這樣也試過:

respond_to do |format| 
    format.json { render json: requests, include: '*', each_serializer: PortalRequestSerializer, scope: current_contact } 
end 

respond_to do |format| 
    format.json { render json: requests, include: '**', each_serializer: PortalRequestSerializer, scope: current_contact } 
end 

但我沒有做任何事情似乎消除了N + 1。我不確定這是否與gem句柄包含嵌套序列化器中的關係有關,或者我只是錯過了某些東西。

UPDATE

下面是從服務器日誌查詢的gist

回答

0

在我看來,你應該從改變你的includes聲明

requests = current_contact.requests.includes(hub_post: [:contact]) 

requests = current_contact.requests.includes(:hub_post, :contact) 
+0

沒有。試過這個,沒有爲我做任何事情。 – ACIDSTEALTH

+0

我覺得有些困惑。它是否「喜歡」你有N + 1問題,或'hub_posts'和'contacts'? –

+0

看看你的關聯,我不太清楚爲什麼當''請求''在'hub_posts'('requests = current_contact.requests.includes(hub_post:[:contact,:likes])''')下嵌套'contacts' '直接與'contacts'和'hub_posts'關聯不是 –

0

我假設你的請求模型contact_id存儲current_contact的ID,所以你可以嘗試:

request = Request.where(contact_id: current_contact.id).includes(:contact, { hub_post: :likes }) 
+0

這並沒有爲N + 1問題做任何事情。我已經嘗試了在'includes'語句中放置':likes'的各種變體,但是沒有任何工作可以 – ACIDSTEALTH

+0

顯示您的日誌。 – Thanh

+0

用鏈接(帖子結束)編輯我的問題以上的日誌的要點。 – ACIDSTEALTH