Module: SupplejackApi::Support::FragmentHelpers

Extended by:
ActiveSupport::Concern
Included in:
PreviewRecord, Record
Defined in:
app/models/supplejack_api/support/fragment_helpers.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *_args) ⇒ Object

Fetch the attribute from the underlying merged_fragment or only fragment. Means that record.attribute (ie. record.name) works for convenience and abstracts away the fact that fragments exist rubocop:disable Style/MethodMissing



75
76
77
78
79
80
81
82
83
84
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 75

def method_missing(symbol, *_args)
  type = fragment_class.mutable_fields[symbol.to_s]

  if merged_fragment
    value = merged_fragment.public_send(symbol)
  elsif fragments.first
    value = fragments.first.public_send(symbol)
  end
  type == Array ? Array(value) : value
end

Instance Method Details

#duplicate_source_ids?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 22

def duplicate_source_ids?
  source_ids.size != fragments.distinct(:source_id).count
end

#find_fragment(source_id) ⇒ Object



91
92
93
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 91

def find_fragment(source_id)
  fragments.where(source_id: source_id).first
end

#merge_fragmentsObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 47

def merge_fragments
  self.merged_fragment = nil

  return unless fragments.size > 1

  self.merged_fragment = fragment_class.new

  fragment_class.mutable_fields.each do |name, field_type|
    if field_type == Array
      values = Set.new
      sorted_fragments.each do |s|
        values += Array(s.public_send(name))
      end
      merged_fragment.public_send("#{name}=", values.to_a)
    else
      values = sorted_fragments.to_a.map { |s| s.public_send(name) }
      merged_fragment.public_send("#{name}=", values.compact.first)
    end
  end

  merged_fragment.unset(:priority)
end

#primary_fragment(attributes = {}) ⇒ Object



38
39
40
41
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 38

def primary_fragment(attributes = {})
  primary = fragments.where(priority: 0).first
  primary ? primary : fragments.build(attributes.merge(priority: 0))
end

#primary_fragment!(attributes = {}) ⇒ Object



43
44
45
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 43

def primary_fragment!(attributes = {})
  primary_fragment(attributes).tap(&:save)
end

#sorted_fragmentsObject

rubocop:enable Style/MethodMissing



87
88
89
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 87

def sorted_fragments
  fragments.sort_by { |s| s.priority || Integer::INT32_MAX }
end

#source_idsObject



18
19
20
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 18

def source_ids
  fragments.map(&:source_id)
end

#validate_unique_source_idsObject



26
27
28
29
30
31
32
33
34
35
36
# File 'app/models/supplejack_api/support/fragment_helpers.rb', line 26

def validate_unique_source_ids
  return unless duplicate_source_ids?

  errors.add(:base, "fragment source_ids must be unique, source_ids: #{source_ids}")
  klass_name = fragment_class.to_s.demodulize.gsub(/Fragment/, '')
  klass_id = "#{klass_name.downcase}_id"
  log_message = "#{klass_name} with #{klass_id}:#{send(klass_id)},"
  log_message += " internal_identifier:#{internal_identifier} failed validation."
  log_message += "  Fragment source_ids must be unique, source_ids: #{source_ids}"
  ValidationLogger.logger.error(log_message)
end