class GraphQL::FancyLoader
HACK: This allows us to import the version number in the gemspec
Constants
- VERSION
Public Class Methods
Get a FancyConnection
wrapping this Loader
# File lib/graphql/fancy_loader.rb, line 29 def self.connection_for(args, key) GraphQL::FancyConnection.new(self, args.except(:context), key, **args.slice(:context)) end
Initialize a FancyLoader
. This takes all the keys which are used to batch, which is a lot of them. Thanks to the design of GraphQL
, however, the frequently-called fields also tend to have the same parameters each time. This means that we can get away with this less-than-ideal batching and still have significant performance gains.
The pagination parameters have some odd interactions to be aware of! They are intersected, so if you pass before and after, you’re specifying after < row < before. That’s pretty logical, but first+last are weirder, because when combined they will return the middle, due to that intersection-driven logic. That is, given a set of 10 rows, first=6 & last=6 will return rows 4, 5, and 6 because they are the only ones in both sets. This isn’t a particularly useful behavior, but the Relay spec is pretty clear that you shouldn’t expect good results if you pass both first and last to the same field.
@param find_by [Symbol, String] the key to find by @param before [Integer] Filter by rows less than this @param after [Integer] Filter by rows greater than this @param first [Integer] Filter for first N rows @param last [Integer] Filter for last N rows @param sort [Array<{:on, :direction => Symbol}>] The sorts to apply while loading
# File lib/graphql/fancy_loader.rb, line 52 def initialize(find_by:, sort:, before: nil, after: 0, first: nil, last: nil, where: nil, context: {}) @find_by = find_by @sort = sort.map(&:to_h) @before = before @after = after @first = first @last = last @where = where @context = context end
Get an autogenerated GraphQL
type for an order input
# File lib/graphql/fancy_loader.rb, line 24 def self.sort_argument @sort_argument ||= GraphQL::FancyLoader::TypeGenerator.new(self).sorts_list end
Public Instance Methods
Perform the loading. Uses {GraphQL::FancyLoader::QueryGenerator} to build a query, then groups the results by the @find_by column, then fulfills all the Promises.
# File lib/graphql/fancy_loader.rb, line 65 def perform(keys) query = QueryGenerator.new( model: model, find_by: @find_by, before: @before, after: @after, first: @first, last: @last, sort: sort, keys: keys, where: @where, context: @context, modify_query: modify_query_lambda ).query results = query.to_a.group_by { |rec| rec[@find_by] } keys.each do |key| fulfill(key, results[key] || []) end end
Private Instance Methods
# File lib/graphql/fancy_loader.rb, line 88 def sort @sort.map do |sort| sorts[sort[:on]].merge(direction: sort[:direction]) end end