graphql-activerecord 0.12.6 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.rubocop.yml +581 -11
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/README.md +69 -37
- data/Rakefile +1 -0
- data/bin/bundle +105 -0
- data/bin/coderay +12 -0
- data/bin/htmldiff +12 -0
- data/bin/ldiff +12 -0
- data/bin/pry +12 -0
- data/bin/rake +12 -0
- data/bin/rspec +12 -0
- data/bin/rubocop +12 -0
- data/bin/ruby-parse +12 -0
- data/bin/ruby-rewrite +12 -0
- data/graphql-activerecord.gemspec +6 -6
- data/lib/graphql/activerecord.rb +6 -2
- data/lib/graphql/models/active_record_extension.rb +2 -1
- data/lib/graphql/models/association_load_request.rb +1 -0
- data/lib/graphql/models/attribute_loader.rb +1 -0
- data/lib/graphql/models/backed_by_model.rb +1 -0
- data/lib/graphql/models/database_types.rb +1 -0
- data/lib/graphql/models/definer.rb +1 -0
- data/lib/graphql/models/definition_helpers.rb +3 -2
- data/lib/graphql/models/definition_helpers/associations.rb +3 -2
- data/lib/graphql/models/definition_helpers/attributes.rb +1 -0
- data/lib/graphql/models/hash_combiner.rb +1 -0
- data/lib/graphql/models/helpers.rb +1 -0
- data/lib/graphql/models/instrumentation.rb +6 -4
- data/lib/graphql/models/monkey_patches/graphql_query_context.rb +1 -0
- data/lib/graphql/models/mutation_field_map.rb +9 -7
- data/lib/graphql/models/mutation_helpers/apply_changes.rb +16 -5
- data/lib/graphql/models/mutation_helpers/authorization.rb +1 -0
- data/lib/graphql/models/mutation_helpers/print_input_fields.rb +4 -3
- data/lib/graphql/models/mutation_helpers/validation.rb +1 -0
- data/lib/graphql/models/mutation_helpers/validation_error.rb +1 -0
- data/lib/graphql/models/mutator.rb +3 -2
- data/lib/graphql/models/promise_relation_connection.rb +1 -0
- data/lib/graphql/models/reflection.rb +2 -0
- data/lib/graphql/models/relation_load_request.rb +1 -0
- data/lib/graphql/models/relation_loader.rb +1 -0
- data/lib/graphql/models/version.rb +2 -1
- metadata +23 -22
    
        data/bin/rspec
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 3 4 | 
             
            #
         | 
| 4 5 | 
             
            # This file was generated by Bundler.
         | 
| 5 6 | 
             
            #
         | 
| @@ -11,6 +12,17 @@ require "pathname" | |
| 11 12 | 
             
            ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
         | 
| 12 13 | 
             
              Pathname.new(__FILE__).realpath)
         | 
| 13 14 |  | 
| 15 | 
            +
            bundle_binstub = File.expand_path("../bundle", __FILE__)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            if File.file?(bundle_binstub)
         | 
| 18 | 
            +
              if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
         | 
| 19 | 
            +
                load(bundle_binstub)
         | 
| 20 | 
            +
              else
         | 
| 21 | 
            +
                abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
         | 
| 22 | 
            +
            Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 14 26 | 
             
            require "rubygems"
         | 
| 15 27 | 
             
            require "bundler/setup"
         | 
| 16 28 |  | 
    
        data/bin/rubocop
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 3 4 | 
             
            #
         | 
| 4 5 | 
             
            # This file was generated by Bundler.
         | 
| 5 6 | 
             
            #
         | 
| @@ -11,6 +12,17 @@ require "pathname" | |
| 11 12 | 
             
            ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
         | 
| 12 13 | 
             
              Pathname.new(__FILE__).realpath)
         | 
| 13 14 |  | 
| 15 | 
            +
            bundle_binstub = File.expand_path("../bundle", __FILE__)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            if File.file?(bundle_binstub)
         | 
| 18 | 
            +
              if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
         | 
| 19 | 
            +
                load(bundle_binstub)
         | 
| 20 | 
            +
              else
         | 
| 21 | 
            +
                abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
         | 
| 22 | 
            +
            Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 14 26 | 
             
            require "rubygems"
         | 
| 15 27 | 
             
            require "bundler/setup"
         | 
| 16 28 |  | 
    
        data/bin/ruby-parse
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 3 4 | 
             
            #
         | 
| 4 5 | 
             
            # This file was generated by Bundler.
         | 
| 5 6 | 
             
            #
         | 
| @@ -11,6 +12,17 @@ require "pathname" | |
| 11 12 | 
             
            ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
         | 
| 12 13 | 
             
              Pathname.new(__FILE__).realpath)
         | 
| 13 14 |  | 
| 15 | 
            +
            bundle_binstub = File.expand_path("../bundle", __FILE__)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            if File.file?(bundle_binstub)
         | 
| 18 | 
            +
              if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
         | 
| 19 | 
            +
                load(bundle_binstub)
         | 
| 20 | 
            +
              else
         | 
| 21 | 
            +
                abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
         | 
| 22 | 
            +
            Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 14 26 | 
             
            require "rubygems"
         | 
| 15 27 | 
             
            require "bundler/setup"
         | 
| 16 28 |  | 
    
        data/bin/ruby-rewrite
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 3 4 | 
             
            #
         | 
| 4 5 | 
             
            # This file was generated by Bundler.
         | 
| 5 6 | 
             
            #
         | 
| @@ -11,6 +12,17 @@ require "pathname" | |
| 11 12 | 
             
            ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
         | 
| 12 13 | 
             
              Pathname.new(__FILE__).realpath)
         | 
| 13 14 |  | 
| 15 | 
            +
            bundle_binstub = File.expand_path("../bundle", __FILE__)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            if File.file?(bundle_binstub)
         | 
| 18 | 
            +
              if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
         | 
| 19 | 
            +
                load(bundle_binstub)
         | 
| 20 | 
            +
              else
         | 
| 21 | 
            +
                abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
         | 
| 22 | 
            +
            Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 14 26 | 
             
            require "rubygems"
         | 
| 15 27 | 
             
            require "bundler/setup"
         | 
| 16 28 |  | 
| @@ -1,6 +1,6 @@ | |
| 1 | 
            -
            # coding: utf-8
         | 
| 2 1 | 
             
            # frozen_string_literal: true
         | 
| 3 | 
            -
             | 
| 2 | 
            +
             | 
| 3 | 
            +
            lib = File.expand_path('lib', __dir__)
         | 
| 4 4 | 
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 5 5 | 
             
            require 'graphql/models/version'
         | 
| 6 6 |  | 
| @@ -20,14 +20,14 @@ Gem::Specification.new do |spec| | |
| 20 20 | 
             
              spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 21 21 | 
             
              spec.require_paths = ["lib"]
         | 
| 22 22 |  | 
| 23 | 
            -
              spec.add_runtime_dependency "activesupport", ">= 4.2", '< 6'
         | 
| 24 23 | 
             
              spec.add_runtime_dependency "activerecord", ">= 4.2", '< 6'
         | 
| 25 | 
            -
              spec.add_runtime_dependency " | 
| 24 | 
            +
              spec.add_runtime_dependency "activesupport", ">= 4.2", '< 6'
         | 
| 25 | 
            +
              spec.add_runtime_dependency "graphql", ">= 1.7.5", '< 2'
         | 
| 26 26 | 
             
              spec.add_runtime_dependency "graphql-batch", ">= 0.2.4"
         | 
| 27 27 |  | 
| 28 28 | 
             
              spec.add_development_dependency "bundler", "~> 1.11"
         | 
| 29 | 
            +
              spec.add_development_dependency "pry"
         | 
| 29 30 | 
             
              spec.add_development_dependency "rake", "~> 10.0"
         | 
| 30 31 | 
             
              spec.add_development_dependency "rspec", "~> 3.0"
         | 
| 31 | 
            -
              spec.add_development_dependency " | 
| 32 | 
            -
              spec.add_development_dependency "rubocop", '~> 0.47.1'
         | 
| 32 | 
            +
              spec.add_development_dependency "rubocop"
         | 
| 33 33 | 
             
            end
         | 
    
        data/lib/graphql/activerecord.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            require 'active_support'
         | 
| 3 4 | 
             
            require 'active_record'
         | 
| 4 5 | 
             
            require 'graphql'
         | 
| @@ -39,6 +40,7 @@ module GraphQL | |
| 39 40 | 
             
              module Models
         | 
| 40 41 | 
             
                class << self
         | 
| 41 42 | 
             
                  attr_accessor :model_from_id, :authorize, :id_for_model, :model_to_graphql_type, :unknown_scalar
         | 
| 43 | 
            +
                  attr_accessor :legacy_nulls
         | 
| 42 44 | 
             
                end
         | 
| 43 45 |  | 
| 44 46 | 
             
                # Returns a promise that will traverse the associations and resolve to the model at the end of the path.
         | 
| @@ -72,11 +74,13 @@ module GraphQL | |
| 72 74 | 
             
                  authorize.call(context, model, action)
         | 
| 73 75 | 
             
                end
         | 
| 74 76 |  | 
| 75 | 
            -
                def self.define_mutator(definer, model_type, null_behavior | 
| 77 | 
            +
                def self.define_mutator(definer, model_type, null_behavior: :leave_unchanged, legacy_nulls: GraphQL::Models.legacy_nulls, &block)
         | 
| 78 | 
            +
                  legacy_nulls ||= false
         | 
| 79 | 
            +
             | 
| 76 80 | 
             
                  # HACK: To get the name of the mutation, to avoid possible collisions with other type names
         | 
| 77 81 | 
             
                  prefix = definer.instance_variable_get(:@target).name
         | 
| 78 82 |  | 
| 79 | 
            -
                  mutator_definition = MutatorDefinition.new(model_type, null_behavior: null_behavior)
         | 
| 83 | 
            +
                  mutator_definition = MutatorDefinition.new(model_type, null_behavior: null_behavior, legacy_nulls: legacy_nulls)
         | 
| 80 84 | 
             
                  mutator_definition.field_map.instance_exec(&block)
         | 
| 81 85 | 
             
                  MutationHelpers.print_input_fields(mutator_definition.field_map, definer, "#{prefix}Input")
         | 
| 82 86 | 
             
                  mutator_definition
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            module GraphQL
         | 
| 3 4 | 
             
              module Models
         | 
| 4 5 | 
             
                module ActiveRecordExtension
         | 
| @@ -24,7 +25,7 @@ module GraphQL | |
| 24 25 | 
             
                  extend ::ActiveSupport::Concern
         | 
| 25 26 | 
             
                  class_methods do
         | 
| 26 27 | 
             
                    def graphql_enum_types
         | 
| 27 | 
            -
                      @ | 
| 28 | 
            +
                      @graphql_enum_types ||= EnumTypeHash.new
         | 
| 28 29 | 
             
                    end
         | 
| 29 30 |  | 
| 30 31 | 
             
                    # Defines a GraphQL enum type on the model
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            require 'ostruct'
         | 
| 3 4 |  | 
| 4 5 | 
             
            module GraphQL
         | 
| @@ -66,7 +67,7 @@ module GraphQL | |
| 66 67 | 
             
                    return false unless context
         | 
| 67 68 |  | 
| 68 69 | 
             
                    reflection = association.reflection
         | 
| 69 | 
            -
                    return false unless [ | 
| 70 | 
            +
                    return false unless %i[has_one belongs_to].include?(reflection.macro)
         | 
| 70 71 |  | 
| 71 72 | 
             
                    if reflection.macro == :belongs_to
         | 
| 72 73 | 
             
                      target_id = model.send(reflection.foreign_key)
         | 
| @@ -123,7 +124,7 @@ module GraphQL | |
| 123 124 | 
             
                    field_name = field_name.to_s
         | 
| 124 125 |  | 
| 125 126 | 
             
                    field_meta = graph_type.instance_variable_get(:@field_metadata)
         | 
| 126 | 
            -
                    field_meta  | 
| 127 | 
            +
                    field_meta ||= graph_type.instance_variable_set(:@field_metadata, {})
         | 
| 127 128 | 
             
                    field_meta[field_name] = OpenStruct.new(metadata).freeze
         | 
| 128 129 | 
             
                  end
         | 
| 129 130 | 
             
                end
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            module GraphQL
         | 
| 3 4 | 
             
              module Models
         | 
| 4 5 | 
             
                module DefinitionHelpers
         | 
| @@ -6,7 +7,7 @@ module GraphQL | |
| 6 7 | 
             
                    reflection = model_type.reflect_on_association(association)
         | 
| 7 8 | 
             
                    raise ArgumentError, "Association #{association} wasn't found on model #{model_type.name}" unless reflection
         | 
| 8 9 | 
             
                    raise ArgumentError, "Cannot proxy to polymorphic association #{association} on model #{model_type.name}" if reflection.polymorphic?
         | 
| 9 | 
            -
                    raise ArgumentError, "Cannot proxy to #{reflection.macro} association #{association} on model #{model_type.name}" unless [ | 
| 10 | 
            +
                    raise ArgumentError, "Cannot proxy to #{reflection.macro} association #{association} on model #{model_type.name}" unless %i[has_one belongs_to].include?(reflection.macro)
         | 
| 10 11 |  | 
| 11 12 | 
             
                    return unless block_given?
         | 
| 12 13 |  | 
| @@ -56,7 +57,7 @@ module GraphQL | |
| 56 57 | 
             
                    reflection = model_type.reflect_on_association(association)
         | 
| 57 58 |  | 
| 58 59 | 
             
                    raise ArgumentError, "Association #{association} wasn't found on model #{model_type.name}" unless reflection
         | 
| 59 | 
            -
                    raise ArgumentError, "Cannot include #{reflection.macro} association #{association} on model #{model_type.name} with has_one" unless [ | 
| 60 | 
            +
                    raise ArgumentError, "Cannot include #{reflection.macro} association #{association} on model #{model_type.name} with has_one" unless %i[has_one belongs_to].include?(reflection.macro)
         | 
| 60 61 |  | 
| 61 62 | 
             
                    # Define the field for the association itself
         | 
| 62 63 |  | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            class GraphQL::Models::Instrumentation
         | 
| 3 4 | 
             
              # @param skip_nil_models If true, field resolvers (in proxy_to or backed_by_model blocks) will not be invoked if the model is nil.
         | 
| 4 5 | 
             
              def initialize(skip_nil_models = true)
         | 
| @@ -12,10 +13,11 @@ class GraphQL::Models::Instrumentation | |
| 12 13 | 
             
                old_resolver = field.resolve_proc
         | 
| 13 14 |  | 
| 14 15 | 
             
                new_resolver = -> (object, args, ctx) {
         | 
| 15 | 
            -
                   | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 16 | 
            +
                  Promise.resolve(field_info.object_to_base_model.call(object)).then do |base_model|
         | 
| 17 | 
            +
                    GraphQL::Models.load_association(base_model, field_info.path, ctx).then do |model|
         | 
| 18 | 
            +
                      next nil if model.nil? && @skip_nil_models
         | 
| 19 | 
            +
                      old_resolver.call(model, args, ctx)
         | 
| 20 | 
            +
                    end
         | 
| 19 21 | 
             
                  end
         | 
| 20 22 | 
             
                }
         | 
| 21 23 |  | 
| @@ -1,14 +1,15 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            module GraphQL::Models
         | 
| 3 4 | 
             
              class MutationFieldMap
         | 
| 4 | 
            -
                attr_accessor :model_type, :find_by, :null_behavior, :fields, :nested_maps
         | 
| 5 | 
            +
                attr_accessor :model_type, :find_by, :null_behavior, :fields, :nested_maps, :legacy_nulls
         | 
| 5 6 |  | 
| 6 7 | 
             
                # These are used when this is a proxy_to or a nested field map
         | 
| 7 8 | 
             
                attr_accessor :name, :association, :has_many, :required, :path
         | 
| 8 9 |  | 
| 9 | 
            -
                def initialize(model_type, find_by:, null_behavior:)
         | 
| 10 | 
            +
                def initialize(model_type, find_by:, null_behavior:, legacy_nulls:)
         | 
| 10 11 | 
             
                  raise ArgumentError, "model_type must be a model" if model_type && !(model_type <= ActiveRecord::Base)
         | 
| 11 | 
            -
                  raise ArgumentError, "null_behavior must be :set_null or :leave_unchanged" unless [ | 
| 12 | 
            +
                  raise ArgumentError, "null_behavior must be :set_null or :leave_unchanged" unless %i[set_null leave_unchanged].include?(null_behavior)
         | 
| 12 13 |  | 
| 13 14 | 
             
                  @fields = []
         | 
| 14 15 | 
             
                  @nested_maps = []
         | 
| @@ -16,6 +17,7 @@ module GraphQL::Models | |
| 16 17 | 
             
                  @model_type = model_type
         | 
| 17 18 | 
             
                  @find_by = Array.wrap(find_by)
         | 
| 18 19 | 
             
                  @null_behavior = null_behavior
         | 
| 20 | 
            +
                  @legacy_nulls = legacy_nulls
         | 
| 19 21 |  | 
| 20 22 | 
             
                  @find_by.each { |f| attr(f) }
         | 
| 21 23 | 
             
                end
         | 
| @@ -65,7 +67,7 @@ module GraphQL::Models | |
| 65 67 | 
             
                  reflection = model_type&.reflect_on_association(association)
         | 
| 66 68 |  | 
| 67 69 | 
             
                  if reflection
         | 
| 68 | 
            -
                    unless [ | 
| 70 | 
            +
                    unless %i[belongs_to has_one].include?(reflection.macro)
         | 
| 69 71 | 
             
                      raise ArgumentError, "Cannot proxy to #{reflection.macro} association #{association} from #{model_type.name}"
         | 
| 70 72 | 
             
                    end
         | 
| 71 73 |  | 
| @@ -74,7 +76,7 @@ module GraphQL::Models | |
| 74 76 | 
             
                    klass = nil
         | 
| 75 77 | 
             
                  end
         | 
| 76 78 |  | 
| 77 | 
            -
                  proxy = MutationFieldMap.new(klass, find_by: nil, null_behavior: null_behavior)
         | 
| 79 | 
            +
                  proxy = MutationFieldMap.new(klass, find_by: nil, null_behavior: null_behavior, legacy_nulls: legacy_nulls)
         | 
| 78 80 | 
             
                  proxy.association = association
         | 
| 79 81 | 
             
                  proxy.instance_exec(&block)
         | 
| 80 82 |  | 
| @@ -97,7 +99,7 @@ module GraphQL::Models | |
| 97 99 | 
             
                  end
         | 
| 98 100 | 
             
                end
         | 
| 99 101 |  | 
| 100 | 
            -
                def nested(association, find_by: nil, null_behavior:, name: nil,  | 
| 102 | 
            +
                def nested(association, find_by: nil, null_behavior:, name: nil, &block)
         | 
| 101 103 | 
             
                  unless model_type
         | 
| 102 104 | 
             
                    raise ArgumentError, "Cannot use `nested` unless the model type is known at build time."
         | 
| 103 105 | 
             
                  end
         | 
| @@ -116,7 +118,7 @@ module GraphQL::Models | |
| 116 118 | 
             
                  has_many = reflection.macro == :has_many
         | 
| 117 119 | 
             
                  required = Reflection.is_required(model_type, association)
         | 
| 118 120 |  | 
| 119 | 
            -
                  map = MutationFieldMap.new(reflection.klass, find_by: find_by, null_behavior: null_behavior)
         | 
| 121 | 
            +
                  map = MutationFieldMap.new(reflection.klass, find_by: find_by, null_behavior: null_behavior, legacy_nulls: legacy_nulls)
         | 
| 120 122 | 
             
                  map.name = name || association.to_s.camelize(:lower)
         | 
| 121 123 | 
             
                  map.association = association.to_s
         | 
| 122 124 | 
             
                  map.has_many = has_many
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            module GraphQL::Models
         | 
| 3 4 | 
             
              module MutationHelpers
         | 
| 4 5 | 
             
                def self.apply_changes(field_map, model, inputs, context)
         | 
| @@ -7,7 +8,13 @@ module GraphQL::Models | |
| 7 8 |  | 
| 8 9 | 
             
                  # Values will now contain the list of inputs that we should actually act on. Any null values should actually
         | 
| 9 10 | 
             
                  # be set to null, and missing fields should be skipped.
         | 
| 10 | 
            -
                  values = field_map.leave_null_unchanged?  | 
| 11 | 
            +
                  values = if field_map.leave_null_unchanged? && field_map.legacy_nulls
         | 
| 12 | 
            +
                    prep_legacy_leave_unchanged(inputs)
         | 
| 13 | 
            +
                  elsif field_map.leave_null_unchanged?
         | 
| 14 | 
            +
                    prep_leave_unchanged(inputs)
         | 
| 15 | 
            +
                  else
         | 
| 16 | 
            +
                    prep_set_null(field_map, inputs)
         | 
| 17 | 
            +
                  end
         | 
| 11 18 |  | 
| 12 19 | 
             
                  values.each do |name, value|
         | 
| 13 20 | 
             
                    field_def = field_map.fields.detect { |f| f[:name] == name }
         | 
| @@ -232,10 +239,10 @@ module GraphQL::Models | |
| 232 239 | 
             
                  end
         | 
| 233 240 | 
             
                end
         | 
| 234 241 |  | 
| 235 | 
            -
                # If the field map has the option leave_null_unchanged, there's an `unsetFields` string | 
| 236 | 
            -
                # name of inputs that should be treated as if they are null. We handle that by removing null | 
| 237 | 
            -
                # adding back any unsetFields with null values.
         | 
| 238 | 
            -
                def self. | 
| 242 | 
            +
                # If the field map has the option leave_null_unchanged, and legacy_nulls is true, then there's an `unsetFields` string
         | 
| 243 | 
            +
                # array that contains the name of inputs that should be treated as if they are null. We handle that by removing null
         | 
| 244 | 
            +
                # inputs, and then adding back any unsetFields with null values.
         | 
| 245 | 
            +
                def self.prep_legacy_leave_unchanged(inputs)
         | 
| 239 246 | 
             
                  # String key hash
         | 
| 240 247 | 
             
                  values = inputs.to_h.compact
         | 
| 241 248 |  | 
| @@ -249,6 +256,10 @@ module GraphQL::Models | |
| 249 256 | 
             
                  values
         | 
| 250 257 | 
             
                end
         | 
| 251 258 |  | 
| 259 | 
            +
                def self.prep_leave_unchanged(inputs)
         | 
| 260 | 
            +
                  inputs.to_h
         | 
| 261 | 
            +
                end
         | 
| 262 | 
            +
             | 
| 252 263 | 
             
                # Field map has the option to set_null. Any field that has the value null, or is missing, will be set to null.
         | 
| 253 264 | 
             
                def self.prep_set_null(field_map, inputs)
         | 
| 254 265 | 
             
                  values = inputs.to_h.compact
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            module GraphQL::Models
         | 
| 3 4 | 
             
              module MutationHelpers
         | 
| 4 5 | 
             
                def self.print_input_fields(field_map, definer, map_name_prefix)
         | 
| @@ -7,14 +8,14 @@ module GraphQL::Models | |
| 7 8 | 
             
                      field_type = f[:type]
         | 
| 8 9 |  | 
| 9 10 | 
             
                      if f[:required] && !field_map.leave_null_unchanged?
         | 
| 10 | 
            -
                        field_type = field_type.to_non_null_type
         | 
| 11 | 
            +
                        field_type = field_type.to_non_null_type unless field_type.non_null?
         | 
| 11 12 | 
             
                      end
         | 
| 12 13 |  | 
| 13 14 | 
             
                      input_field(f[:name], field_type)
         | 
| 14 15 | 
             
                    end
         | 
| 15 16 |  | 
| 16 | 
            -
                    if field_map.leave_null_unchanged?
         | 
| 17 | 
            -
                      field_names = field_map.fields. | 
| 17 | 
            +
                    if field_map.leave_null_unchanged? && field_map.legacy_nulls
         | 
| 18 | 
            +
                      field_names = field_map.fields.reject { |f| f[:required] }.map { |f| f[:name].to_s }
         | 
| 18 19 | 
             
                      field_names += field_map.nested_maps.reject(&:required).map { |fld| fld.name.to_s }
         | 
| 19 20 | 
             
                      field_names = field_names.sort
         | 
| 20 21 |  |