Module: Rails::GraphQL::Helpers::WithFields
- Included in:
- Alternative::FieldSet, Type::Input, Type::Interface, Type::Object
- Defined in:
- lib/rails/graphql/helpers/with_fields.rb
Overview
Helper module that allows other objects to hold fields during the definition process. Works very similar to Arguments, but it’s more flexible, since the type of the fields can be dynamic defined by the class that extends this module.
Fields, different from arguments, has extended types, which is somewhat related to the base type, but it’s closer associated with the strategy used to handle them.
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
-
#change_field(object, **xargs, &block) ⇒ Object
(also: #overwrite_field)
Overwrite attributes of a given field named as
name, it also allows ablockwhich will then further configure the field. -
#configure_field(object, &block) ⇒ Object
Perform extra configurations on a given
field. -
#disable_fields(*list) ⇒ Object
Disable a list of given
fields. -
#enable_fields(*list) ⇒ Object
Enable a list of given
fields. -
#enabled_fields ⇒ Object
Return a lazy enumerator for enabled fields.
-
#field(name, *args, **xargs, &block) ⇒ Object
See Field class.
-
#field_names(enabled_only = true) ⇒ Object
Get the list of GraphQL names of all the fields defined.
-
#find_by_gid(gid) ⇒ Object
Find a specific field using its id as
gql_name.type. -
#find_field(object) ⇒ Object
(also: #[])
Allow accessing fields using the hash notation.
-
#find_field!(object) ⇒ Object
If the field is not found it will raise an exception.
-
#has_field?(object) ⇒ Boolean
Check whether a given field
objectis defined in the list of fields. -
#import(source) ⇒ Object
Import one or more field into the current list of fields.
-
#import_all(mod, recursive: false, **xargs) ⇒ Object
Import a module containing several classes to be imported.
-
#proxy_field(field, *args, **xargs, &block) ⇒ Object
Add a new field to the list but use a proxy instead of a hard copy of a given
field. -
#safe_field(*args, of_type: nil, **xargs, &block) ⇒ Object
Check if the field is already defined before actually creating it.
-
#validate! ⇒ Object
Validate all the fields to make sure the definition is valid.
Class Method Details
.extended(other) ⇒ Object
36 37 38 39 40 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 36 def self.extended(other) other.extend(WithFields::ClassMethods) other.class_attribute(:field_type, instance_accessor: false) other.class_attribute(:valid_field_types, instance_accessor: false, default: []) end |
Instance Method Details
#change_field(object, **xargs, &block) ⇒ Object Also known as: overwrite_field
Overwrite attributes of a given field named as name, it also allows a block which will then further configure the field
82 83 84 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 82 def change_field(object, **xargs, &block) find_field!(object).apply_changes(**xargs, &block) end |
#configure_field(object, &block) ⇒ Object
Perform extra configurations on a given field
89 90 91 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 89 def configure_field(object, &block) find_field!(object).configure(&block) end |
#disable_fields(*list) ⇒ Object
Disable a list of given fields
94 95 96 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 94 def disable_fields(*list) list.flatten.map { |item| self[item]&.disable! } end |
#enable_fields(*list) ⇒ Object
Enable a list of given fields
99 100 101 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 99 def enable_fields(*list) list.flatten.map { |item| self[item]&.enable! } end |
#enabled_fields ⇒ Object
Return a lazy enumerator for enabled fields
132 133 134 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 132 def enabled_fields lazy_each_field&.select(&:enabled?) end |
#field(name, *args, **xargs, &block) ⇒ Object
See Field class.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 51 def field(name, *args, **xargs, &block) object = field_type.new(name, *args, **xargs, owner: self, &block) raise DuplicatedError, (+<<~MSG).squish if has_field?(object.name) The #{name.inspect} field is already defined and can't be redefined. MSG fields(true)[object.name] = object rescue DefinitionError => e raise e.class, +"#{e.}\n Defined at: #{caller(2)[0]}" end |
#field_names(enabled_only = true) ⇒ Object
Get the list of GraphQL names of all the fields defined
127 128 129 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 127 def field_names(enabled_only = true) (enabled_only ? enabled_fields : lazy_each_field)&.map(&:gql_name)&.eager end |
#find_by_gid(gid) ⇒ Object
Find a specific field using its id as gql_name.type
179 180 181 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 179 def find_by_gid(gid) find_field!(gid.name) end |
#find_field(object) ⇒ Object Also known as: []
Allow accessing fields using the hash notation
111 112 113 114 115 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 111 def find_field(object) return unless fields? object = object.name if object.is_a?(GraphQL::Field) fields[object.is_a?(String) ? object.underscore.to_sym : object] end |
#find_field!(object) ⇒ Object
If the field is not found it will raise an exception
120 121 122 123 124 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 120 def find_field!(object) find_field(object) || raise(NotFoundError, (+<<~MSG).squish) The #{object.inspect} field is not defined yet. MSG end |
#has_field?(object) ⇒ Boolean
Check whether a given field object is defined in the list of fields
104 105 106 107 108 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 104 def has_field?(object) return false unless fields? object = object.name if object.is_a?(GraphQL::Field) fields.key?(object.is_a?(String) ? object.underscore.to_sym : object) end |
#import(source) ⇒ Object
Import one or more field into the current list of fields
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 137 def import(source) # Import an alternative declaration of a field if source.is_a?(Module) && source <= Alternative::Query return proxy_field(source.field) end case source when Array # Import a list of fields source.each { |field| proxy_field(field) } when Hash, Concurrent::Map # Import a keyed list of fields source.each_value { |field| proxy_field(field) } when Helpers::WithFields # Import a set of fields source.fields.each_value { |field| proxy_field(field) } else return if GraphQL.config.silence_import_warnings GraphQL.logger.warn(+"Unable to import #{source.inspect} into #{self.name}.") end end |
#import_all(mod, recursive: false, **xargs) ⇒ Object
Import a module containing several classes to be imported
160 161 162 163 164 165 166 167 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 160 def import_all(mod, recursive: false, **xargs) mod.constants.each do |const_name| object = mod.const_get(const_name, false) import(object, **xargs) if object.is_a?(Class) import_all(object, recursive: recursive, **xargs) if recursive && object.is_a?(Module) end end |
#proxy_field(field, *args, **xargs, &block) ⇒ Object
Add a new field to the list but use a proxy instead of a hard copy of a given field
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 65 def proxy_field(field, *args, **xargs, &block) field = field.field if field.is_a?(Module) && field <= Alternative::Query raise ArgumentError, (+<<~MSG).squish unless field.is_a?(field_type) The #{field.class.name} is not a valid field. MSG xargs[:owner] = self object = field.to_proxy(*args, **xargs, &block) raise DuplicatedError, (+<<~MSG).squish if has_field?(object.name) The #{field.name.inspect} field is already defined and can't be replaced. MSG fields(true)[object.name] = object end |
#safe_field(*args, of_type: nil, **xargs, &block) ⇒ Object
Check if the field is already defined before actually creating it
43 44 45 46 47 48 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 43 def safe_field(*args, of_type: nil, **xargs, &block) method_name = of_type.nil? ? :field : "#{of_type}_field" public_send(method_name, *args, **xargs, &block) rescue DuplicatedError # Do not do anything if it is duplicated end |
#validate! ⇒ Object
Validate all the fields to make sure the definition is valid
170 171 172 173 174 175 176 |
# File 'lib/rails/graphql/helpers/with_fields.rb', line 170 def validate!(*) super if defined? super # TODO: Maybe find a way to freeze the fields, since after validation # the best thing to do is block changes fields&.each_value(&:validate!) end |