Skip to content

Instantly share code, notes, and snippets.

@itkrt2y
Last active September 3, 2024 11:45
Show Gist options
  • Save itkrt2y/1e1a947c71772044f5d67f358b4772fc to your computer and use it in GitHub Desktop.
Save itkrt2y/1e1a947c71772044f5d67f358b4772fc to your computer and use it in GitHub Desktop.

Revisions

  1. itkrt2y revised this gist Mar 10, 2022. 1 changed file with 40 additions and 0 deletions.
    40 changes: 40 additions & 0 deletions example.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    class User < ApplicationRecord
    has_many :posts
    end
    class Post < ApplicationRecord
    belongs_to :user
    has_many :comments
    end
    class Comment < ApplicationRecord
    belongs_to :post
    end

    module Types
    class UserType < Types::BaseObject
    field :id, ID, null: false
    field :posts, [Types::PostType], null: false
    def posts
    dataloader.with(Sources::Association, :posts, ::Post.preload(:comments)).load(object)
    end
    end

    class PostType < Types::BaseObject
    field :id, ID, null: false
    field :user, Types::UserType, null: false
    def user
    dataloader.with(Sources::Association, :user).load(object)
    end
    field :comments, [Types::CommentType], null: false
    def comments
    dataloader.with(Sources::Association, :comments).load(object)
    end
    end

    class CommentType < Types::BaseObject
    field :id, ID, null: false
    field :post, Types::PostType, null: false
    def post
    dataloader.with(Sources::Association, :post).load(object)
    end
    end
    end
  2. itkrt2y revised this gist Mar 10, 2022. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions association.rb
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,6 @@
    # official docs: https://graphql-ruby.org/dataloader/sources.html

    # app/graphql/sources/association.rb
    # frozen_string_literal: true

    class Sources::Association < ::GraphQL::Dataloader::Source
    def initialize(association_name, scope = nil)
    @association_name = association_name
  3. itkrt2y revised this gist Mar 10, 2022. 1 changed file with 9 additions and 7 deletions.
    16 changes: 9 additions & 7 deletions association.rb
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,12 @@
    # official docs: https://graphql-ruby.org/dataloader/sources.html

    # app/graphql/sources/association.rb
    # frozen_string_literal: true

    class Sources::Association < ::GraphQL::Dataloader::Source
    def initialize(association_name, preload_model = nil, preload_scope = nil)
    def initialize(association_name, scope = nil)
    @association_name = association_name

    # `dataloader.with(Sources::Association, :foo, Model.preload(scope))` のように
    # 最初からpreloadしたクラスを渡すと処理がbatchにならないため、別々に渡した上で内部で結合する
    @scope = if preload_model && preload_scope
    preload_model.preload(preload_scope)
    end
    @scope = scope
    end

    def fetch(records)
    @@ -18,4 +15,9 @@ def fetch(records)
    # ::ActiveRecord::Associations::Preloader.new(records: records, associations: @association_name, scope: @scope).call
    records.map { |record| record.public_send(@association_name) }
    end

    # https://github.com/rmosolgo/graphql-ruby/blob/821ca53048fa5803fb90596719b4fedd65029ecb/lib/graphql/dataloader/source.rb#L113-L129
    def self.batch_key_for(*batch_args, **batch_kwargs)
    [*batch_args.map { |arg| arg.try(:to_sql) || arg }, **batch_kwargs]
    end
    end
  4. itkrt2y revised this gist Mar 10, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion association.rb
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ def initialize(association_name, preload_model = nil, preload_scope = nil)
    def fetch(records)
    ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name, @scope)
    # Rails7
    # ::ActiveRecord::Associations::Preloader.new.preload(records: records, associations: @association_name, scope: @scope).call
    # ::ActiveRecord::Associations::Preloader.new(records: records, associations: @association_name, scope: @scope).call
    records.map { |record| record.public_send(@association_name) }
    end
    end
  5. itkrt2y revised this gist Mar 10, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion association.rb
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ def initialize(association_name, preload_model = nil, preload_scope = nil)
    def fetch(records)
    ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name, @scope)
    # Rails7
    # ::ActiveRecord::Associations::Preloader.new.preload(records: records, associations: @association_name, scope: @scope)
    # ::ActiveRecord::Associations::Preloader.new.preload(records: records, associations: @association_name, scope: @scope).call
    records.map { |record| record.public_send(@association_name) }
    end
    end
  6. itkrt2y revised this gist Mar 10, 2022. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions association.rb
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,8 @@ def initialize(association_name, preload_model = nil, preload_scope = nil)

    def fetch(records)
    ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name, @scope)
    # Rails7
    # ::ActiveRecord::Associations::Preloader.new.preload(records: records, associations: @association_name, scope: @scope)
    records.map { |record| record.public_send(@association_name) }
    end
    end
  7. itkrt2y created this gist Mar 10, 2022.
    19 changes: 19 additions & 0 deletions association.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    # official docs: https://graphql-ruby.org/dataloader/sources.html

    # app/graphql/sources/association.rb
    class Sources::Association < ::GraphQL::Dataloader::Source
    def initialize(association_name, preload_model = nil, preload_scope = nil)
    @association_name = association_name

    # `dataloader.with(Sources::Association, :foo, Model.preload(scope))` のように
    # 最初からpreloadしたクラスを渡すと処理がbatchにならないため、別々に渡した上で内部で結合する
    @scope = if preload_model && preload_scope
    preload_model.preload(preload_scope)
    end
    end

    def fetch(records)
    ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name, @scope)
    records.map { |record| record.public_send(@association_name) }
    end
    end