module UniverseCompiler::Entity::FieldManagement

Private Instance Methods

define_field_accessor(field_name) click to toggle source
# File lib/universe_compiler/entity/field_management.rb, line 67
def define_field_accessor(field_name)
  metaclass = class << self; self ; end
  UniverseCompiler.logger.debug 'Defining field accessor %s on class %s (%s)' % [field_name, metaclass, self.type]
  define_field_reader(field_name, metaclass)
  define_field_writer(field_name, metaclass)
end
define_field_reader(field_name, metaclass) click to toggle source
# File lib/universe_compiler/entity/field_management.rb, line 86
def define_field_reader(field_name, metaclass)
  if self.respond_to? field_name
    UniverseCompiler.logger.info "'#{field_name}' already exists on class '#{metaclass}'. Skipped !"
  else
    metaclass.instance_eval do
      define_method field_name do
        fields[field_name]
      end
    end
  end
end
define_field_writer(field_name, metaclass) click to toggle source
# File lib/universe_compiler/entity/field_management.rb, line 74
def define_field_writer(field_name, metaclass)
  if self.respond_to? "#{field_name}="
    UniverseCompiler.logger.info "'#{field_name}=' already exists on class '#{metaclass}'. Skipped !"
  else
    metaclass.instance_eval do
      define_method "#{field_name}=" do |value|
        fields[field_name] = value
      end
    end
  end
end
define_known_fields_accessors() click to toggle source
# File lib/universe_compiler/entity/field_management.rb, line 56
def define_known_fields_accessors
  self.class.fields_constraints.each do |field_name, constraints|
    next if constraints[:reverse_method]
    define_field_accessor field_name
    if fields[field_name].nil?
      fields[field_name] = [] if constraints[:has_many] || constraints[:is_array]
      fields[field_name] = {} if constraints[:is_hash]
    end
  end
end
define_reverse_method(method_name, method_definition_constraints) click to toggle source
# File lib/universe_compiler/entity/field_management.rb, line 16
def define_reverse_method(method_name, method_definition_constraints)
  metaclass = class << self; self ; end
  UniverseCompiler.logger.debug 'Defining reverse method "%s" on class %s (%s)' % [method_name, metaclass, self.type]
  raise UniverseCompiler::Error, "'#{method_name}' already exists on class '#{metaclass}'. Skipped !" if self.respond_to? method_name
  method_definition_constraints[:actual_method] = method_name

  check_operation = case method_definition_constraints[:relation_type]
                    when :has_one
                      '=='.to_sym
                    when :has_many
                      'include?'.to_sym
                    end

  metaclass.instance_eval do
    define_method method_name do
      raise UniverseCompiler::Error, "Entity '#{as_path}' is not in a universe. Reverse methods can't work !" if universe.nil?

      res = universe.get_entities(criterion: :by_type, value: method_definition_constraints[:source_entity]).select do |entity|
        entity[method_definition_constraints[:source_field]].send check_operation, self
      end
      if res.empty?
        res = nil if method_definition_constraints[:unique_result]
        return res
      end

      if method_definition_constraints[:unique_result]
        if res.size == 1
          return res.first
        else
          UniverseCompiler.logger.warn 'Too many results. Must be one or none !'
          UniverseCompiler.logger.debug res.inspect
          raise UniverseCompiler::Error, "'#{self.as_path}##{method_name}' should return maximum one '#{method_definition_constraints[:source_entity]}' !"
        end
      end

      res
    end
  end
end
define_reverse_methods() click to toggle source
# File lib/universe_compiler/entity/field_management.rb, line 8
def define_reverse_methods
  self.class.fields_constraints.each do |method_name, constraints|
    next unless constraints[:reverse_method]

    define_reverse_method method_name, constraints[:reverse_method]
  end
end