Module: Ecoportal::API::GraphQL::Logic::Input::IdDiffFields

Included in:
Input::ContractorEntity::Update
Defined in:
lib/ecoportal/api/graphql/logic/input.rb

Overview

Declarative set-diff macro for id-list fields that the schema exposes as IdDiffInput { additions: [ID!], removals: [ID!] } on the update mutation.

Mixed into any Input class (whether it inherits from Ecoportal::API::GraphQL::Logic::Input or from a Base:: data model) via extend. Ecoportal::API::GraphQL::Logic::Input extends it for its own subclasses; data-model Input classes call extend Logic::Input::IdDiffFields explicitly.

Usage:

class Update < Base::ContractorEntity
extend Logic::Input::IdDiffFields
id_diff_fields :associatedPeopleIds, :leadContractorIds
end

It installs (or augments) a from_model that, for each declared field, computes the delta DIRECTLY from the READ model's doc[key] vs original_doc[key] arrays:

additions = current - original
removals  = original - current

A field is omitted when unchanged. The delta is computed directly (NOT via the cascaded DiffService) because these array fields are dropped from the flat diff and the read model is root! (so its doc/original_doc resolve without cascade side effects).

Instance Method Summary collapse

Instance Method Details

#from_model(model, **kargs) ⇒ Hash?

Reshaping from_model: base diff (via Ecoportal::API::GraphQL::Logic::Input.from_model) + set-diff deltas.

Parameters:

Returns:

  • (Hash, nil)

    the mutation input hash, or nil when there are no changes.



63
64
65
66
# File 'lib/ecoportal/api/graphql/logic/input.rb', line 63

def from_model(model, **kargs)
  diff = Logic::Input.from_model(model, **kargs)
  merge_id_diffs(model, diff)
end

#id_diff_fields(*fields) ⇒ void

This method returns an undefined value.

Declares the id-list fields that must be reshaped into IdDiff { additions:, removals: }.

Parameters:

  • fields (Array<Symbol>)

    field names (as they appear in the read model's doc).



37
38
39
# File 'lib/ecoportal/api/graphql/logic/input.rb', line 37

def id_diff_fields(*fields)
  id_diff_fields_list.concat(fields.flatten.map(&:to_sym)).uniq!
end

#id_diff_fields_listArray<Symbol>

Returns the fields declared for set-diff on this class.

Returns:

  • (Array<Symbol>)

    the fields declared for set-diff on this class.



30
31
32
# File 'lib/ecoportal/api/graphql/logic/input.rb', line 30

def id_diff_fields_list
  @id_diff_fields_list ||= []
end

#merge_id_diffs(model, diff) ⇒ Hash?

Computes the IdDiff-shaped deltas for the declared fields and merges them into diff.

Parameters:

  • model (Common::GraphQL::Model)

    the subject (read) model.

  • diff (Hash, nil)

    the base mutation input hash to augment (may be nil).

Returns:

  • (Hash, nil)

    diff with per-field { additions:, removals: } merged in, or the original value when nothing changed.



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ecoportal/api/graphql/logic/input.rb', line 46

def merge_id_diffs(model, diff)
  id_diff_fields_list.each do |field|
    key      = field.to_s
    current  = Array(model.doc[key])
    original = Array(model.original_doc[key])
    next if current == original

    diff        ||= {}
    diff[:id]   ||= model.id if model.respond_to?(:id)
    diff[field]   = { additions: current - original, removals: original - current }
  end
  diff
end