lib/rails/graphql/helpers/inherited_collection.rb in rails-graphql-0.2.1 vs lib/rails/graphql/helpers/inherited_collection.rb in rails-graphql-1.0.0.beta
- old
+ new
@@ -1,17 +1,24 @@
# frozen_string_literal: true
-module Rails # :nodoc:
- module GraphQL # :nodoc:
- module Helpers # :nodoc:
- module InheritedCollection # :nodoc:
+module Rails
+ module GraphQL
+ module Helpers
+ # Helper module that allow classes to have specific type of attributes
+ # that are corretly delt when it is inherited by another class. It keeps
+ # track of its own value and allow access to all values of the property
+ # in the tree,
+ #
+ # TODO: Rewrite this!
+ module InheritedCollection
+ # All possible types of inheritable values
DEFAULT_TYPES = {
array: '[]',
set: 'Set.new',
hash: '{}',
- hash_array: 'Hash.new { |h, k| h[k] = [] }',
- hash_set: 'Hash.new { |h, k| h[k] = Set.new }',
+ hash_array: '::Hash.new { |h, k| h[k] = [] }',
+ hash_set: '::Hash.new { |h, k| h[k] = Set.new }',
}.freeze
# Declare a class-level attribute whose value is both isolated and also
# inherited from parent classes. Subclasses can change their own value
# and it will not impact parent class.
@@ -58,95 +65,37 @@
instance_reader: true,
instance_predicate: true,
type: :set
)
attrs.each do |name|
- module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
- def self.all_#{name}
- ::Rails::GraphQL::Helpers::AttributeDelegator.new do
- fetch_inherited_#{type}('@#{name}')
- end
+ instance_eval(<<~RUBY, __FILE__, __LINE__ + 1)
+ def all_#{name}
+ return superclass.try(:all_#{name}) unless defined?(@#{name})
+ InheritedCollection::Base.handle(self, :@#{name}, :#{type})
end
- def self.#{name}
+ def #{name}
@#{name} ||= #{DEFAULT_TYPES[type]}
end
RUBY
- module_eval(<<~RUBY, __FILE__, __LINE__ + 1) if instance_predicate
- def self.#{name}?
+ instance_eval(<<~RUBY, __FILE__, __LINE__ + 1) if instance_predicate
+ def #{name}?
(defined?(@#{name}) && @#{name}.present?) || superclass.try(:#{name}?)
end
RUBY
if instance_reader
delegate(name.to_sym, :"all_#{name}", to: :class)
delegate(:"#{name}?", to: :class) if instance_predicate
end
end
end
-
- protected
-
- # Combine an inherited list of arrays
- def fetch_inherited_array(ivar)
- inherited_ancestors.each_with_object([]) do |klass, result|
- next result unless klass.instance_variable_defined?(ivar)
- val = klass.instance_variable_get(ivar)
- result.merge(val) unless val.blank?
- end
- end
-
- # Combine an inherited list of set objects
- def fetch_inherited_set(ivar)
- inherited_ancestors.each_with_object(Set.new) do |klass, result|
- next result unless klass.instance_variable_defined?(ivar)
- val = klass.instance_variable_get(ivar)
- result.merge(val) unless val.blank?
- end
- end
-
- # Combine an inherited list of hashes but keeping only the most recent
- # value, which means that keys might be replaced
- def fetch_inherited_hash(ivar)
- inherited_ancestors.each_with_object({}) do |klass, result|
- next result unless klass.instance_variable_defined?(ivar)
- val = klass.instance_variable_get(ivar)
- result.merge!(val) unless val.blank?
- end
- end
-
- # Right now we can't use Hash with default proc for equivalency due to
- # a bug on Ruby https://bugs.ruby-lang.org/issues/17181
-
- # Combine an inherited list of hashes, which also will combine arrays,
- # ensuring that same key items will be combined
- def fetch_inherited_hash_array(ivar)
- inherited_ancestors.inject({}) do |result, klass|
- next result unless klass.instance_variable_defined?(ivar)
- val = klass.instance_variable_get(ivar)
- Helpers.merge_hash_array(result, val)
- end
- end
-
- # Combine an inherited list of hashes, which also will combine arrays,
- # ensuring that same key items will be combined
- def fetch_inherited_hash_set(ivar)
- inherited_ancestors.inject({}) do |result, klass|
- next result unless klass.instance_variable_defined?(ivar)
- val = klass.instance_variable_get(ivar)
- Helpers.merge_hash_array(result, val)
- end
- end
-
- private
-
- # Return a list of all the ancestor classes up until object
- def inherited_ancestors
- [self].tap do |list|
- list.unshift(list.first.superclass) until list.first.superclass === Object
- end
- end
end
end
end
end
+
+require_relative 'inherited_collection/base'
+
+require_relative 'inherited_collection/array'
+require_relative 'inherited_collection/hash'