Module: Familia::Horreum::RelatedFieldsManagement::RelatedFieldsAccessors

Defined in:
lib/familia/horreum/subclass/related_fields_management.rb

Instance Method Summary collapse

Instance Method Details

Sets up all DataType related methods This method generates the following for each registered DataType:

Instance methods: set(), list(), hashkey(), sorted_set(), etc. Query methods: set?(), list?(), hashkey?(), sorted_set?(), etc. Collection methods: sets(), lists(), hashkeys(), sorted_sets(), etc. Class methods: class_set(), class_list(), etc.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/familia/horreum/subclass/related_fields_management.rb', line 39

def setup_related_fields_accessors
  Familia::DataType.registered_types.each_pair do |kind, klass|
    Familia.trace :registered_types, kind, klass, caller(1..1) if Familia.debug?

    # Dynamically define instance-level relation methods
    #
    # Once defined, these methods can be used at the instance-level of a
    # Familia member to define *instance-level* relations to any of the
    # DataType types (e.g. set, list, hash, etc).
    #
    define_method :"#{kind}" do |*args|
      name, opts = *args

      # As log as we have at least one relation, we can set this flag.
      @has_relations = true

      attach_instance_related_field name, klass, opts
    end
    define_method :"#{kind}?" do |name|
      obj = related_fields[name.to_s.to_sym]
      !obj.nil? && klass == obj.klass
    end
    define_method :"#{kind}s" do
      names = related_fields.keys.select { |name| send(:"#{kind}?", name) }
      names.collect! { |name| related_fields[name] }
      names
    end

    # Dynamically define class-level relation methods
    #
    # Once defined, these methods can be used at the class-level of a
    # Familia member to define *class-level relations* to any of the
    # DataType types (e.g. class_set, class_list, class_hash, etc).
    #
    define_method :"class_#{kind}" do |*args|
      name, opts = *args
      attach_class_related_field name, klass, opts
    end
    define_method :"class_#{kind}?" do |name|
      obj = class_related_fields[name.to_s.to_sym]
      !obj.nil? && klass == obj.klass
    end
    define_method :"class_#{kind}s" do
      names = class_related_fields.keys.select { |name| send(:"class_#{kind}?", name) }
      # TODO: This returns instances of the DataType class which
      # also contain the options. This is different from the instance
      # DataTypes defined above which returns the Struct of name, klass, and opts.
      # names.collect! { |name| self.send name }
      # OR NOT:
      names.collect! { |name| class_related_fields[name] }
      names
    end
  end
end