Class: GraphQL::FancyLoader
- Inherits:
-
Batch::Loader
- Object
- Batch::Loader
- GraphQL::FancyLoader
- Includes:
- ActiveSupport::Configurable, DSL
- Defined in:
- lib/graphql/fancy_loader/version.rb,
lib/graphql/fancy_loader.rb,
lib/graphql/fancy_loader/dsl.rb,
lib/graphql/fancy_loader/type_generator.rb,
lib/graphql/fancy_loader/query_generator.rb,
lib/graphql/fancy_loader/pagination_filter.rb,
lib/graphql/fancy_loader/rank_query_generator.rb
Overview
HACK: This allows us to import the version number in the gemspec
Defined Under Namespace
Modules: DSL Classes: PaginationFilter, PunditMiddleware, QueryGenerator, RankQueryGenerator, TypeGenerator
Constant Summary collapse
- VERSION =
.3
'0.1.5'.freeze
Class Method Summary collapse
-
.connection_for(args, key) ⇒ Object
Get a FancyConnection wrapping this Loader.
-
.sort_argument ⇒ Object
Get an autogenerated GraphQL type for an order input.
Instance Method Summary collapse
-
#initialize(find_by:, sort:, before: nil, after: 0, first: nil, last: nil, where: nil, context: {}) ⇒ FancyLoader
constructor
Initialize a FancyLoader.
-
#perform(keys) ⇒ Object
Perform the loading.
Constructor Details
#initialize(find_by:, sort:, before: nil, after: 0, first: nil, last: nil, where: nil, context: {}) ⇒ FancyLoader
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.
52 53 54 55 56 57 58 59 60 61 |
# 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 |
Class Method Details
.connection_for(args, key) ⇒ Object
Get a FancyConnection wrapping this Loader
29 30 31 |
# 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 |
.sort_argument ⇒ Object
Get an autogenerated GraphQL type for an order input
24 25 26 |
# File 'lib/graphql/fancy_loader.rb', line 24 def self.sort_argument @sort_argument ||= GraphQL::FancyLoader::TypeGenerator.new(self).sorts_list end |
Instance Method Details
#perform(keys) ⇒ Object
Perform the loading. Uses QueryGenerator to build a query, then groups the results by the @find_by column, then fulfills all the Promises.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# 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 |