Class: Rails::GraphQL::Source::ActiveRecordSource
- Inherits:
-
Base
- Object
- Rails::GraphQL::Source
- Base
- Rails::GraphQL::Source::ActiveRecordSource
- Extended by:
- MySQL::SourceMethods, PG::SourceMethods, Rails::GraphQL::SQLite::SourceMethods, Builders
- Includes:
- ScopedArguments
- Defined in:
- lib/rails/graphql/source/active_record_source.rb
Overview
GraphQL Source Active Record
This source allows the translation of active record objects into a new source object, creating:
-
1 Object
-
1 Input
-
2 Query fields (singular and plural)
-
3 Mutation fields (create, update, destroy)
Defined Under Namespace
Modules: Builders
Constant Summary
Constants included from Helpers::WithSchemaFields
Helpers::WithSchemaFields::TYPE_FIELD_CLASS
Constants included from Helpers::InheritedCollection
Helpers::InheritedCollection::DEFAULT_TYPES
Constants included from Helpers::WithCallbacks
Helpers::WithCallbacks::DEFAULT_EVENT_TYPES
Instance Attribute Summary
Attributes included from Helpers::Instantiable
Class Method Summary collapse
-
.assigned_to ⇒ Object
Set the assignment to a model with a similar name as the source.
-
.collection_field ⇒ Object
Provides access to the default plural query field, for associations interconnection.
-
.enums ⇒ Object
Stores columns associated with enums so that the fields can have a correctly assigned type.
-
.interface? ⇒ Boolean
Checks if the source is building an interface instead of an object.
-
.unregister! ⇒ Object
Hook into the unregister to clean enums.
Instance Method Summary collapse
-
#build_association_scope(association) ⇒ Object
Collect a scope for filters applied to a given association.
-
#create_record ⇒ Object
The perform step for the
create
based mutation. -
#destroy_record ⇒ Object
The perform step for the
delete
based mutation. -
#errors_to_extensions(errors, path = nil, format = nil) ⇒ Object
Expose the errors to the extensions of the response.
-
#load_record(scope = nil, find_by: nil) ⇒ Object
Prepare to load a single record from the underlying model.
-
#load_records(scope = nil) ⇒ Object
Prepare to load multiple records from the underlying model.
-
#parent_owned_records(collection_result = false) ⇒ Object
Once the records are pre-loaded due to
preload_association
, use the parent value and the preloader result to get the records. -
#preload_association(association, scope = nil) ⇒ Object
Get the chain result and preload the records with the resulting scope.
-
#update_record ⇒ Object
The perform step for the
update
based mutation.
Methods included from Builders
build_primary_key_arguments, each_attribute, each_reflection, id_columns
Methods included from ScopedArguments
Methods inherited from Base
Methods included from Helpers::WithSchemaFields
#[], #add_field, #add_proxy_field, #change_field, #configure_field, #configure_fields, #disable_fields, #enable_fields, #enabled_fields_from, extended, #field_names_for, #fields_for, #fields_for?, #find_by_gid, #find_field, #find_field!, #has_field?, #import_all, #import_all_into, #import_into, #safe_add_field, #type_name_for, #validate!
Methods included from Helpers::WithAssignment
#assigned?, #assigned_class, #assigned_to, #assigned_to=, extended, #register!, #safe_assigned_class, #valid_assignment?
Methods included from Helpers::Unregisterable
Methods inherited from Rails::GraphQL::Source
attach_fields!, base_name, base_type_class, find_for, find_for!, kind, schemas, step
Methods included from Helpers::InheritedCollection
Methods included from Helpers::WithNamespace
#namespace, #namespaces, #set_namespace
Methods included from Helpers::WithEvents
Methods included from Helpers::WithCallbacks
Methods included from Builder
#build_all, #build_all_sources, #built?, #method_missing, #respond_to_missing?
Class Method Details
.assigned_to ⇒ Object
Set the assignment to a model with a similar name as the source
127 128 129 130 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 127 def assigned_to return @assigned_to if defined?(@assigned_to) @assigned_to = base_name.gsub('_', '::') end |
.collection_field ⇒ Object
Provides access to the default plural query field, for associations interconnection
156 157 158 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 156 def collection_field find_field(:query, plural) end |
.enums ⇒ Object
Stores columns associated with enums so that the fields can have a correctly assigned type
134 135 136 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 134 def enums @enums ||= model.defined_enums.dup end |
.interface? ⇒ Boolean
Checks if the source is building an interface instead of an object
150 151 152 153 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 150 def interface? defined?(@interface) || act_as_interface == true || (act_as_interface != false && sti_interface?) end |
.unregister! ⇒ Object
Hook into the unregister to clean enums
161 162 163 164 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 161 def unregister! super @enums = nil end |
Instance Method Details
#build_association_scope(association) ⇒ Object
Collect a scope for filters applied to a given association
242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 242 def build_association_scope(association) scope = model._reflect_on_association(association).klass.default_scoped # Apply proxied injected scopes # TODO: Arguments comes with their proxy, so we might not need this # proxied = event.field.try(:proxied_owner) # scope = event.on_instance(proxied) do |instance| # instance.inject_scopes(scope, :relation) # end if proxied.present? && proxied <= Source::ActiveRecordSource # Apply self defined injected scopes inject_scopes(scope, :relation) end |
#create_record ⇒ Object
The perform step for the create
based mutation
213 214 215 216 217 218 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 213 def create_record input_argument.resource.tap(&:save!) rescue ::ActiveRecord::RecordInvalid => error errors_to_extensions(error.record.errors) raise end |
#destroy_record ⇒ Object
The perform step for the delete
based mutation
229 230 231 232 233 234 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 229 def destroy_record !!current_value.destroy! rescue ::ActiveRecord::RecordInvalid => error errors_to_extensions(error.record.errors) raise end |
#errors_to_extensions(errors, path = nil, format = nil) ⇒ Object
Expose the errors to the extensions of the response
273 274 275 276 277 278 279 280 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 273 def errors_to_extensions(errors, path = nil, format = nil) format ||= self.class.errors_to_extensions return unless format path ||= [operation.name, field.gql_name].compact hash = GraphQL.enumerate(path).reduce(request.extensions) { |h, k| h[k] ||= {} } hash.replace(format == :messages ? errors.as_json : errors.details) end |
#load_record(scope = nil, find_by: nil) ⇒ Object
Prepare to load a single record from the underlying model
206 207 208 209 210 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 206 def load_record(scope = nil, find_by: nil) scope ||= event.last_result || model.default_scoped find_by ||= { primary_key => event.argument(primary_key) } inject_scopes(scope, :relation).find_by(find_by) end |
#load_records(scope = nil) ⇒ Object
Prepare to load multiple records from the underlying model
200 201 202 203 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 200 def load_records(scope = nil) scope ||= event.last_result || model.default_scoped inject_scopes(scope, :relation) end |
#parent_owned_records(collection_result = false) ⇒ Object
Once the records are pre-loaded due to preload_association
, use the parent value and the preloader result to get the records
258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 258 def parent_owned_records(collection_result = false) # The absence of the prepared data key means we got to a point that we # don't know the result of the association, so we simply call it unless event.data.key?(:prepared_data) return current_value.public_send(field.method_name) end data = event.data[:prepared_data] return collection_result ? [] : nil unless data result = data.records_by_owner[current_value] || [] collection_result ? result : result.first end |
#preload_association(association, scope = nil) ⇒ Object
Get the chain result and preload the records with the resulting scope
237 238 239 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 237 def preload_association(association, scope = nil) event.stop(preload(association, scope || event.last_result), layer: :object) end |
#update_record ⇒ Object
The perform step for the update
based mutation
221 222 223 224 225 226 |
# File 'lib/rails/graphql/source/active_record_source.rb', line 221 def update_record current_value.tap { |record| record.update!(**input_argument.params) } rescue ::ActiveRecord::RecordInvalid => error errors_to_extensions(error.record.errors) raise end |