module HQ::GraphQL::Resource::ClassMethods
Attributes
graphql_name[W]
model_name[W]
Public Instance Methods
const_missing(constant_name)
click to toggle source
Calls superclass method
# File lib/hq/graphql/resource.rb, line 88 def const_missing(constant_name) constant_name = constant_name.to_sym case constant_name when :Query query_object when :NilQuery nil_query_object when :Input input_klass when :FilterInput filter_input when :FilterFields filter_fields_enum else super end end
filter_fields_enum()
click to toggle source
# File lib/hq/graphql/resource.rb, line 122 def filter_fields_enum @filter_fields_enum ||= begin scoped_self = self enum_class = Class.new(::GraphQL::Schema::Enum) do graphql_name "#{scoped_self.graphql_name}FilterFields" lazy_load do scoped_self.model_klass.columns.sort_by(&:name).each do |column| next unless HQ::GraphQL::Filters.supported?(column) value column.name.camelize(:lower), value: column end end end const_set(:FilterFields, enum_class) end end
filter_input()
click to toggle source
# File lib/hq/graphql/resource.rb, line 106 def filter_input @filter_input ||= begin scoped_self = self input_class = Class.new(::GraphQL::Schema::InputObject) do graphql_name "#{scoped_self.graphql_name}FilterInput" argument :field, scoped_self.filter_fields_enum, required: true argument :operation, Enum::FilterOperation, required: true argument :value, String, required: true end const_set(:FilterInput, input_class) end end
find_record(attrs, context)
click to toggle source
# File lib/hq/graphql/resource.rb, line 35 def find_record(attrs, context) primary_key = model_klass.primary_key.to_sym primary_key_value = attrs[primary_key] scope(context).find_by(primary_key => primary_key_value) end
graphql_name()
click to toggle source
# File lib/hq/graphql/resource.rb, line 45 def graphql_name @graphql_name || model_name.demodulize end
input_klass()
click to toggle source
# File lib/hq/graphql/resource.rb, line 61 def input_klass @input_klass ||= build_input_object end
model_klass()
click to toggle source
# File lib/hq/graphql/resource.rb, line 53 def model_klass @model_klass ||= model_name&.safe_constantize end
model_name()
click to toggle source
# File lib/hq/graphql/resource.rb, line 49 def model_name @model_name || ::HQ::GraphQL.extract_class(self) end
mutation_klasses()
click to toggle source
# File lib/hq/graphql/resource.rb, line 57 def mutation_klasses @mutation_klasses ||= {}.with_indifferent_access end
new_record(context)
click to toggle source
# File lib/hq/graphql/resource.rb, line 41 def new_record(context) scope(context).new end
nil_query_object()
click to toggle source
# File lib/hq/graphql/resource.rb, line 65 def nil_query_object @nil_query_object ||= const_set(:NilQuery, build_graphql_object(name: "#{graphql_name}Copy", auto_nil: false)) end
query_object()
click to toggle source
# File lib/hq/graphql/resource.rb, line 69 def query_object @query_object ||= begin qo = if @query_object_options options, block = @query_object_options @query_object_options = nil build_graphql_object(**options, &block) else build_graphql_object end remove_const(:Query) if const_defined?(:Query, false) const_set(:Query, qo) end end
scope(context)
click to toggle source
# File lib/hq/graphql/resource.rb, line 29 def scope(context) scope = model_klass scope = ::HQ::GraphQL.default_scope(scope, context) @default_scope&.call(scope, context) || scope end
sort_fields_enum()
click to toggle source
# File lib/hq/graphql/resource.rb, line 84 def sort_fields_enum @sort_fields_enum || ::HQ::GraphQL::Enum::SortBy end
Protected Instance Methods
def_root(field_name, is_array: false, null: true, &block)
click to toggle source
# File lib/hq/graphql/resource.rb, line 174 def def_root(field_name, is_array: false, null: true, &block) resource = self resolver = -> { klass = Class.new(::GraphQL::Schema::Resolver) do type = is_array ? [resource.query_object] : resource.query_object type type, null: null class_eval(&block) if block end constant_name = "#{field_name.to_s.classify}Resolver" resource.send(:remove_const, constant_name) if resource.const_defined?(constant_name, false) resource.const_set(constant_name, klass) } ::HQ::GraphQL.root_queries << { field_name: field_name, resolver: resolver, model_name: model_name } end
default_scope(&block)
click to toggle source
# File lib/hq/graphql/resource.rb, line 143 def default_scope(&block) @default_scope = block end
excluded_inputs(*fields)
click to toggle source
# File lib/hq/graphql/resource.rb, line 170 def excluded_inputs(*fields) @excluded_inputs = fields end
input(**options, &block)
click to toggle source
# File lib/hq/graphql/resource.rb, line 147 def input(**options, &block) @input_klass = build_input_object(**options, &block) end
mutations(create: true, copy: true, update: true, destroy: true)
click to toggle source
# File lib/hq/graphql/resource.rb, line 151 def mutations(create: true, copy: true, update: true, destroy: true) mutation_klasses["create_#{graphql_name.underscore}"] = build_create if create mutation_klasses["copy_#{graphql_name.underscore}"] = build_copy if copy mutation_klasses["update_#{graphql_name.underscore}"] = build_update if update mutation_klasses["destroy_#{graphql_name.underscore}"] = build_destroy if destroy end
query(**options, &block)
click to toggle source
# File lib/hq/graphql/resource.rb, line 158 def query(**options, &block) @query_object_options = [options, block] end
query_class(klass)
click to toggle source
# File lib/hq/graphql/resource.rb, line 162 def query_class(klass) @query_class = klass end
root_query(find_one: true, find_all: true, pagination: true, limit_max: 250)
click to toggle source
# File lib/hq/graphql/resource.rb, line 192 def root_query(find_one: true, find_all: true, pagination: true, limit_max: 250) field_name = graphql_name.underscore scoped_self = self if find_one def_root field_name, is_array: false, null: true do klass = scoped_self.model_klass primary_key = klass.primary_key argument primary_key, ::GraphQL::Types::ID, required: true define_method(:resolve) do |**attrs| scoped_self.find_record(attrs, context) end end end if find_all def_root field_name.pluralize, is_array: true, null: false do extension FieldExtension::PaginatedArguments, klass: scoped_self.model_klass if pagination argument :filters, [scoped_self.filter_input], required: false define_method(:resolve) do |filters: nil, limit: nil, offset: nil, sort_by: nil, sort_order: nil, **_attrs| filters_scope = ::HQ::GraphQL::Filters.new(filters, scoped_self.model_klass) filters_scope.validate! scope = scoped_self.scope(context).all.merge(filters_scope.to_scope) if pagination || page || limit offset = [0, *offset].max limit = [[limit_max, *limit].min, 0].max scope = scope.limit(limit).offset(offset) end sort_by ||= :updated_at sort_order ||= :desc # There should be no risk for SQL injection since an enum is being used for both sort_by and sort_order scope = scope.reorder(sort_by => sort_order) scope end end end end
sort_fields(*fields)
click to toggle source
# File lib/hq/graphql/resource.rb, line 166 def sort_fields(*fields) self.sort_fields_enum = fields end
Private Instance Methods
build_graphql_object(name: graphql_name, **options, &block)
click to toggle source
# File lib/hq/graphql/resource.rb, line 239 def build_graphql_object(name: graphql_name, **options, &block) scoped_graphql_name = name scoped_model_name = model_name object_class = @query_class || ::HQ::GraphQL.default_object_class || ::GraphQL::Schema::Object Class.new(object_class) do graphql_name scoped_graphql_name with_model scoped_model_name, **options class_eval(&block) if block end end
build_input_object(**options, &block)
click to toggle source
# File lib/hq/graphql/resource.rb, line 252 def build_input_object(**options, &block) scoped_graphql_name = graphql_name scoped_model_name = model_name scoped_excluded_inputs = @excluded_inputs || [] input_klass = Class.new(::GraphQL::Schema::InputObject) do graphql_name "#{scoped_graphql_name}Input" with_model scoped_model_name, excluded_inputs: scoped_excluded_inputs, **options class_eval(&block) if block end remove_const(:Input) if const_defined?(:Input, false) const_set(:Input, input_klass) end
sort_fields_enum=(fields)
click to toggle source
# File lib/hq/graphql/resource.rb, line 269 def sort_fields_enum=(fields) @sort_fields_enum ||= Class.new(::HQ::GraphQL::Enum::SortBy).tap do |c| c.graphql_name "#{graphql_name}Sort" const_set(:Sort, c) end Array(fields).each do |field| @sort_fields_enum.value field.to_s.classify, value: field end end