Last active
June 17, 2021 04:13
-
-
Save patorash/be7fe58e9a2d3237db67c619f6cd9948 to your computer and use it in GitHub Desktop.
ElasticsearchRelationConnection for graphqu-ruby with elasticsearch-model
This file contains hidden or 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 Connections | |
class ElasticsearchRelationConnection < GraphQL::Pagination::RelationConnection | |
def nodes | |
@nodes ||= limited_nodes.records.to_a | |
end | |
# Rubocopにload_nodesメソッドが不要と言われた | |
# しかし、継承元のRelationConnectionで呼ばれているのでnodesメソッドのエイリアスにしておく | |
# また、元々private methodだったので変更しておく | |
alias_method :load_nodes, :nodes | |
private :load_nodes | |
# GraphQL::Pagination::RelationConnectionの実装を改修 | |
# `@paged_node_offset`にオフセットが入っているので、2重で足さないようにした。 | |
def cursor_for(item) | |
load_nodes | |
# index in nodes + existing offset + 1 (because it's offset, not index) | |
# offset = @nodes.index(item) + 1 + (@paged_nodes_offset || 0) + (relation_offset(items) || 0) | |
offset = @nodes.index(item) + 1 + (@paged_nodes_offset || 0) | |
encode(offset.to_s) | |
end | |
private | |
# @param [Elasticsearch::Model::Response::Response] | |
# @param [Integer] size LimitSize | |
# @return [Boolean] sizeよりも残りが大きければtrueを返す | |
def relation_larger_than(relation, size) | |
initial_offset = relation_offset(relation) | |
relation_count(relation) > initial_offset + size | |
end | |
# @param [Elasticsearch::Model::Response::Response] | |
# @return [Integer] オフセットの値 | |
def relation_offset(relation) | |
relation.search.definition.fetch(:from, 0) | |
end | |
# @param [Elasticsearch::Model::Response::Response] | |
# @return [Integer, nil] 取得数 | |
def relation_limit(relation) | |
relation.search.definition[:size] | |
end | |
# @param [Elasticsearch::Model::Response::Response] | |
# @return [Integer] 総ヒット数 | |
def relation_count(relation) | |
relation.results.total | |
end | |
# @param [Elasticsearch::Model::Response::Response] | |
# @return [ActiveRecord::Relation] | |
def null_relation(relation) | |
relation.records.none | |
end | |
def limited_nodes | |
super() | |
rescue ArgumentError => _e | |
# カーソルの先頭より前の要素を取得しようとするとArgumentErrorになったため、 | |
# 例外を補足して空のActiveRecord::Relationを返すようにした | |
ApplicationRecord.none | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment