Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rmosolgo/d857a53c5349b6b2191d1a3d995cd5c0 to your computer and use it in GitHub Desktop.
Save rmosolgo/d857a53c5349b6b2191d1a3d995cd5c0 to your computer and use it in GitHub Desktop.
SearchObjectGraphQL lookahead example
require 'bundler/inline'
gemfile do
gem "graphql", "2.4.15"
gem "search_object_graphql", "1.0.5"
gem "activerecord", require: "active_record"
gem "sqlite3"
end
require 'search_object'
require 'search_object/plugin/graphql'
# Set up the database for the example
ActiveRecord::Base.establish_connection({ adapter: "sqlite3", database: ":memory:" })
ActiveRecord::Schema.define do
self.verbose = false
create_table :users, force: true do |t|
t.string :username
t.timestamps
end
end
class User < ActiveRecord::Base; end
20.times do |i|
User.create!(username: "User-#{i}")
end
# Define a minimal schema for demonstrating this integration.
# Many types, fields, and arguments are skipped over.
class MySchema < GraphQL::Schema
class User < GraphQL::Schema::Object
field :username, String
end
class Sidebar < GraphQL::Schema::Object
field :users, User.connection_type
end
class SidebarResolver < GraphQL::Schema::Resolver
include SearchObject.module(:graphql)
# ** Here, request that GraphQL-Ruby injects a lookahead into `def resolve`
extras([:lookahead])
type(Sidebar, null: false)
scope { ::User.all }
option :username, type: String, with: :filter_username, default: nil
# ** Here, catch the incoming lookahead and use it for something
def resolve(lookahead:, **rest)
# This is how you'd find the offset value:
users_arguments = lookahead.selection(:users).arguments
if (offset_cursor = users_arguments[:after])
# Store the offset value here, then use `@offset` in other methods.
@offset = Base64.decode64(offset_cursor).to_i
pp [:offset_value, @offset]
end
# (@offset will be `nil` if no value was given in the arguments --
# you could also assign it to `0` in an `else` case here if you want)
super
end
def filter_username(scope, value)
if value
scope = scope.where("username LIKE ?", "%#{value}%")
end
{ users: scope }
end
end
class Pass < GraphQL::Schema::Object
field :sidebar, resolver: SidebarResolver
end
class Query < GraphQL::Schema::Object
field :pass, Pass, fallback_value: Object.new
end
query(Query)
end
# A couple of test queries:
query_str = <<-GRAPHQL
{
pass {
sidebar {
users(first: 10, after: "OA==") {
nodes {
username
}
}
}
}
}
GRAPHQL
pp MySchema.execute(query_str).to_h
# [:offset_value, 8]
# {"data" =>
# {"pass" =>
# {"sidebar" =>
# {"users" =>
# {"nodes" =>
# [{"username" => "User-8"},
# {"username" => "User-9"},
# {"username" => "User-10"},
# {"username" => "User-11"},
# {"username" => "User-12"},
# {"username" => "User-13"},
# {"username" => "User-14"},
# {"username" => "User-15"},
# {"username" => "User-16"},
# {"username" => "User-17"}]}}}}}
pp MySchema.execute(<<-GRAPHQL).to_h
{
pass {
sidebar {
users {
nodes {
username
}
}
}
}
}
GRAPHQL
# {"data" =>
# {"pass" =>
# {"sidebar" =>
# {"users" =>
# {"nodes" =>
# [{"username" => "User-0"},
# ...
# {"username" => "User-19"}]}}}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment