Created
October 23, 2020 08:32
-
-
Save andersklenke/c4b41ad58af66ac378395968633e7bec to your computer and use it in GitHub Desktop.
GraphQL loaders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Loaders | |
class ForeignKeyLoader < GraphQL::Batch::Loader | |
attr_reader :model, :foreign_key, :merge | |
def self.loader_key_for(*group_args) | |
# avoiding including the `merge` lambda in loader key | |
# each lambda is unique which defeats the purpose of | |
# grouping queries together | |
[self].concat(group_args.slice(0, 2)) | |
end | |
def initialize(model, foreign_key, merge: nil) | |
@model = model | |
@foreign_key = foreign_key | |
@merge = merge | |
end | |
def perform(foreign_ids) | |
# find all the records | |
scope = model.where(foreign_key => foreign_ids) | |
scope = scope.merge(merge) if merge.present? | |
records = scope.to_a | |
foreign_ids.each do |foreign_id| | |
# find the records required to fulfill each promise | |
matching_records = records.select do |r| | |
foreign_id == r.send(foreign_key) | |
end | |
fulfill(foreign_id, matching_records) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Loaders | |
class RecordLoader < GraphQL::Batch::Loader | |
EMPTY_ARRAY = [].freeze | |
def initialize(model, column: model.primary_key, where: nil, unique: true) | |
@model = model | |
@column = column | |
@column_type = model.type_for_attribute(@column.to_s) | |
@where = where | |
@unique = unique | |
end | |
def load(key) | |
super(@column_type.cast(key)) | |
end | |
def perform(keys) | |
if @unique | |
query(keys).each do |record| | |
fulfill(record.public_send(@column), record) | |
end | |
default = nil | |
else | |
query(keys).group_by(&@column).each do |key, result| | |
fulfill(key, result) | |
end | |
default = EMPTY_ARRAY | |
end | |
keys.each { |key| fulfill(key, default) unless fulfilled?(key) } | |
end | |
private | |
def query(keys) | |
scope = @model | |
scope = scope.where(@where) if @where | |
scope.where(@column => keys) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Her bruger jeg record_loader | |
Loaders::RecordLoader.for(::Partner).load(object.partner_id) | |
# Her bruger jeg foreign_key_loader og en record_loader inden i | |
Loaders::ForeignKeyLoader.for(TeamMembership, :team_id).load(object.id).then do |memberships| | |
Loaders::RecordLoader.for(User).load_many(memberships.map(&:user_id)) | |
end | |
# Mere avanceret forkeign key loader hvor et scope bliver merget ind | |
Loaders::ForeignKeyLoader.for( | |
Episode, :playlist_id, merge: -> { Episode.ordered_by_newest_episode } | |
).load(object.id) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment