我第一次尝试GraphQL、分页和Rails中的批加载。我需要一些人帮忙调查引擎盖下面发生的事情。我使用GraphQL::Batch。这是我的两个Qraphql类型(精简),表示1对多(has_many,belongs_to pair in AR)关系:
module Types
  class GoalType < Types::BaseObject
    field :id, ID, null: false
    field :title, String
    field :tags_connection, Types::TagType.connection_type
    def tags_connection
      Loaders::RecordLoader.for(::Tag).load_many(object.tag_ids)
    end
  end
end
module Types
  class TagType < Types::BaseObject
    field :id, ID, null: false
    field :name, String
  end
end
下面是查询根实现:
field :goals_connection, Types::GoalType.connection_type, null: false
    def goals_connection
      Goal.all
    end
到目前为止,我可以得到分页列表,并且它工作正常(好吧,我仍然对查询的数量有问题,这比imo要多,但这是另一个问题)。问题是,当我像下面这样运行查询时:
query GoalQuery {
  goalsConnection(first: 2) {
    nodes {
      id
      title
      tagsConnection(first: 2) {
        nodes {
          name
          eventsCounter
        }
      }
    }
  }
}
我看到生成了以下SQL语句:
Goal Load (0.1ms) SELECT "goals".* FROM "goals" LIMIT ? OFFSET ? [["LIMIT", 2], ["OFFSET", 0]] Tag Pluck (0.1ms) SELECT "tags"."id" FROM "tags" WHERE "tags"."goal_id" = ? ORDER BY events_counter desc LIMIT ? [["goal_id", 1], ["LIMIT", 100]] Tag Pluck (0.2ms) SELECT "tags"."id" FROM "tags" WHERE "tags"."goal_id" = ? ORDER BY events_counter desc LIMIT ? [["goal_id", 2], ["LIMIT", 100]] Tag Load (0.2ms) SELECT "tags".* FROM "tags" WHERE "tags"."id" IN (?, ?, ?, ?, ?, ?, ?) [["id", 2], ["id", 1], ["id", 3], ["id", 4], ["id", 5], ["id", 6], ["id", 7]]
所以,我的困惑是这里LIMIT的用法。Goal上的第一个查询是根据请求的页面添加LIMIT和OFFSET。但是,嵌套连接正在设置一个LIMIT = 100,这与我的页面请求没有任何关系,而且我没有在任何地方设置值100(甚至在default_max_page_size和default_page_size上也没有)。那么,为什么限制为100,以及如何应用页面大小?一天结束后,我得到了正确的页面,除了顶层实体之外,它都在内存中吗?
我已经更改了查询根实现以预加载连接:
field :goals_connection, Types::GoalType.connection_type, null: false
    def goals_connection
      Goal.preload(:tags)
    end
它去掉了额外的查询,但上面仍然有limit: 100。我没有使用preload的原因是我担心它无法正确应用分页限制,因为我读到你不能对预加载的关联设置约束。但是,现在即使没有预加载,我也看到类似的事情发生了。所以,也许预加载是正确的方式,除了可能我一开始没有正确实现分页?