我有以下型號:添加包括參數渲染方法不能解決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_posts
和likes
請求,然後返回一個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。
沒有。試過這個,沒有爲我做任何事情。 – ACIDSTEALTH
我覺得有些困惑。它是否「喜歡」你有N + 1問題,或'hub_posts'和'contacts'? –
看看你的關聯,我不太清楚爲什麼當''請求''在'hub_posts'('requests = current_contact.requests.includes(hub_post:[:contact,:likes])''')下嵌套'contacts' '直接與'contacts'和'hub_posts'關聯不是 –