# frozen_string_literal: true require "global_registry" module GlobalRegistry # :nodoc: module Bindings # :nodoc: module Entity # :nodoc: module RelationshipTypeMethods extend ActiveSupport::Concern # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/AbcSize def push_global_registry_relationship_type return unless global_registry_relationship(type).ensure_type? primary_entity_type_id = primary_associated_entity_type_id related_entity_type_id = related_associated_entity_type_id relationship_type = Rails.cache.fetch(relationship_type_cache_key, expires_in: 1.hour) do rel = GlobalRegistry::RelationshipType.get( "filters[between]" => "#{primary_entity_type_id},#{related_entity_type_id}" )["relationship_types"].detect do |r| r["relationship1"]["relationship_name"] == global_registry_relationship(type).primary_name.to_s end unless rel rel = GlobalRegistry::RelationshipType.post( relationship_type: { entity_type1_id: primary_entity_type_id, entity_type2_id: related_entity_type_id, relationship1: global_registry_relationship(type).primary_name, relationship2: global_registry_relationship(type).related_name } )["relationship_type"] rename_relationship_entity_type(rel) end rel end push_global_registry_relationship_type_fields(relationship_type) relationship_type end # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/AbcSize def primary_associated_entity_type_id primary_worker = GlobalRegistry::Bindings::Workers::PushEntityWorker.new global_registry_relationship(type).primary entity_type = primary_worker.send(:push_entity_type_to_global_registry) unless entity_type primary_type = global_registry_relationship(type).primary_type entity_type = GlobalRegistry::EntityType.get( "filters[name]" => primary_type )["entity_types"]&.first end entity_type&.dig("id") end def related_associated_entity_type_id unless global_registry_relationship(type).related related_type = global_registry_relationship(type).related_type # remote foreign_key doesn't have a model class in rails. Short-circuit and fetch entity_type by name entity_type = GlobalRegistry::EntityType.get( "filters[name]" => related_type )["entity_types"]&.first unless entity_type raise GlobalRegistry::Bindings::RelatedEntityTypeMissing, "#{model.class.name}(#{model.id}) has unknown related entity_type(#{related_type}) in " \ "global_registry. Entity Type must exist in Global Registry for remote foreign_key relationship." end return entity_type&.dig("id") end related_worker = GlobalRegistry::Bindings::Workers::PushEntityWorker.new global_registry_relationship(type).related related_worker.send(:push_entity_type_to_global_registry)&.dig("id") end def push_global_registry_relationship_type_fields(relationship_type) existing_fields = relationship_type["fields"]&.collect { |f| f["name"].to_sym } || [] fields = model.relationship_columns_to_push(type) .except(*existing_fields) .map { |name, type| {name: name, field_type: type} } return if fields.empty? relationship_type = GlobalRegistry::RelationshipType.put(relationship_type["id"], relationship_type: {fields: fields}) &.dig("relationship_type") Rails.cache.write(relationship_type_cache_key, relationship_type, expires_in: 1.hour) if relationship_type end def rename_relationship_entity_type(relationship_type) return unless global_registry_relationship(type).rename_entity_type? entity_type_id = relationship_type&.dig("relationship_entity_type_id") GlobalRegistry::EntityType.put(entity_type_id, entity_type: {id: entity_type_id, name: global_registry_relationship(type).type}) end def relationship_type_cache_key "GlobalRegistry::Bindings::RelationshipType::#{global_registry_relationship(type).primary_type}::" \ "#{global_registry_relationship(type).related_type}::" \ "#{global_registry_relationship(type).primary_name}" end end end end end