Module: LcpRuby::Metadata::ModelHashMerger
- Defined in:
- lib/lcp_ruby/metadata/model_hash_merger.rb
Overview
Merges a parent (abstract) model hash into a child model hash. Operates on raw hashes before ModelDefinition.from_hash is called.
Constant Summary collapse
- NAMED_ARRAY_KEYS =
Named-array keys: arrays of hashes where each item has a “name” key. Child items with the same name override parent items; child-only items are appended.
Set.new(%w[fields associations scopes events]).freeze
- HASH_KEYS =
Hash keys: merged by key, child wins on collision.
Set.new(%w[virtual_columns display_templates]).freeze
- ADDITIVE_ARRAY_KEYS =
Additive array keys: concatenated, no override by name.
Set.new(%w[validations indexes]).freeze
- IDENTITY_KEYS =
Identity keys: never inherited, always child’s own.
Set.new(%w[name table_name label label_plural slug_field]).freeze
- STRIP_KEYS =
Keys stripped from the merged result.
Set.new(%w[abstract inherits]).freeze
Class Method Summary collapse
-
.merge(parent_hash, child_hash) ⇒ Object
All other keys (positioning, data_source, etc.) fall through to the default branch: child wins if present, otherwise inherited from parent.
Class Method Details
.merge(parent_hash, child_hash) ⇒ Object
All other keys (positioning, data_source, etc.) fall through to the default branch: child wins if present, otherwise inherited from parent.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/lcp_ruby/metadata/model_hash_merger.rb', line 27 def self.merge(parent_hash, child_hash) result = {} # Start with parent as base, skip identity/strip keys parent_hash.each do |key, value| next if IDENTITY_KEYS.include?(key) || STRIP_KEYS.include?(key) result[key] = value.deep_dup end # Apply child values child_hash.each do |key, value| next if STRIP_KEYS.include?(key) if IDENTITY_KEYS.include?(key) result[key] = value elsif NAMED_ARRAY_KEYS.include?(key) result[key] = merge_named_arrays(result[key], value) elsif HASH_KEYS.include?(key) result[key] = (result[key] || {}).merge(child_hash[key] || {}) elsif ADDITIVE_ARRAY_KEYS.include?(key) result[key] = concat_arrays(result[key], value) elsif key == "options" result[key] = (result[key] || {}).deep_merge(value || {}) else # Scalar keys and any unknown keys: child wins result[key] = value.deep_dup end end # Clean up empty collections result.delete_if { |k, v| (v.is_a?(Array) && v.empty?) || (v.is_a?(Hash) && v.empty?) } result end |