Skip to content

Instantly share code, notes, and snippets.

@rmosolgo
Last active November 23, 2021 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmosolgo/12e738d6983b412e666424e64f13cae5 to your computer and use it in GitHub Desktop.
Save rmosolgo/12e738d6983b412e666424e64f13cae5 to your computer and use it in GitHub Desktop.
GraphQL Connections With ActiveRecord Connection Switching
require "bundler/inline"
gemfile do
gem "graphql", "1.12.20"
gem "graphql-pro", "1.20.2"
gem "rails"
gem "sqlite3"
end
require "active_record"
ActiveRecord::Base.legacy_connection_handling = false
ActiveRecord::Base.configurations = {
primary: { adapter: "sqlite3", database: "ar_test.db" },
replica: { adapter: "sqlite3", database: "ar_test.db", replica: true },
}
ActiveRecord::Base.establish_connection(:primary)
ActiveRecord::Schema.define do
self.verbose = false
create_table :things, force: true do |t|
t.column :name, :string
end
end
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :primary, reading: :replica }
end
class Thing < ApplicationRecord
end
Thing.create!(name: "Hat")
Thing.create!(name: "Lamp")
Thing.create!(name: "Tree")
class SqliteReadConnection < GraphQL::Pro::SqliteStableRelationConnection
def load_nodes
puts "Connecting to Reading"
ActiveRecord::Base.connected_to(role: :reading) { super }
ensure
puts "Disconnecting from Reading"
end
end
class Schema < GraphQL::Schema
class Thing < GraphQL::Schema::Object
field :name, String, null: false
end
class Query < GraphQL::Schema::Object
field :things, Thing.connection_type, null: false
def things
SqliteReadConnection.new(::Thing.all)
end
end
query(Query)
connections.add(ActiveRecord::Relation, GraphQL::Pro::SqliteStableRelationConnection)
end
ActiveRecord::Base.logger = Logger.new(STDOUT)
pp Schema.execute("{ things(first: 5) { nodes { name } } }").to_h
# After: it runs just one database query for the GraphQL query:
#
# ~/code/graphql-ruby $ ruby ar-connections-test.rb
# Connecting to Reading
# D, [2021-11-23T09:19:50.011583 #56567] DEBUG -- : (0.0ms) SELECT sqlite_version(*)
# D, [2021-11-23T09:19:50.011926 #56567] DEBUG -- : Thing Load (0.1ms) SELECT things.*, things.id AS cursor_0 FROM "things" ORDER BY things.id asc LIMIT ? [["LIMIT", 6]]
# Disconnecting from Reading
# {"data"=>
# {"things"=>{"nodes"=>[{"name"=>"Hat"}, {"name"=>"Lamp"}, {"name"=>"Tree"}]}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment