我有以下型号:
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和{{ 1}} adapter)像这样:
:json
这当然是一个明显的N + 1问题(Bullet宝石出人意料地似乎没有这个问题)。查看日志时,我可以看到每个hub_post的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
语句。现在我尝试包括SELECT
,如此:
likes
有趣的是Bullet宝石没有在N + 1上获得,但是Scout却没有。
我也尝试根据documentation向我的render方法添加requests = current_contact.requests.includes(hub_post: [:contact, :likes])
requests = current_contact.requests.includes(hub_post: [contact: [:likes]])
参数,如下所示:
include
我也尝试过使用单级和多级通配符,如下所示:
respond_to do |format|
format.json { render json: requests, include: 'hub_posts,hub_posts.likes', each_serializer: PortalRequestSerializer, scope: current_contact }
end
然而我所做的一切似乎都没有消除N + 1。我不确定这是宝石如何处理嵌套序列化器中的关系或者我是否只是遗漏某些东西的问题。
更新
以下是来自服务器日志的gist查询。
答案 0 :(得分:0)
在我看来,您应该从
更改includes
声明
requests = current_contact.requests.includes(hub_post: [:contact])
到
requests = current_contact.requests.includes(:hub_post, :contact)
答案 1 :(得分:0)
我假设您的请求模型有contact_id
来存储current_contact的ID,因此您可以尝试:
request = Request.where(contact_id: current_contact.id).includes(:contact, { hub_post: :likes })