Class: Lore::Associations

Inherits:
Object show all
Defined in:
lib/lore/model/associations.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(accessor) ⇒ Associations

Returns a new instance of Associations.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/lore/model/associations.rb', line 48

def initialize(accessor)
  @accessor = accessor
  @foreign_keys = {}
  @primary_keys = {}
  
  @has_a = {}
  @has_n = {}
  @belongs_to = {}
  
  @base_klasses = {}
  @base_klasses_tree = {}
  @aggregate_klasses = {}
  @aggregates_tree = {}

  @pkey_value_lookup = []

  @polymorphics = {}
  @concrete_models = []

  @joins = false
end

Instance Attribute Details

#aggregate_klassesObject (readonly)

Returns the value of attribute aggregate_klasses.



12
13
14
# File 'lib/lore/model/associations.rb', line 12

def aggregate_klasses
  @aggregate_klasses
end

#aggregatesObject (readonly)

Returns the value of attribute aggregates.



13
14
15
# File 'lib/lore/model/associations.rb', line 13

def aggregates
  @aggregates
end

#aggregates_treeObject (readonly)

Returns the value of attribute aggregates_tree.



15
16
17
# File 'lib/lore/model/associations.rb', line 15

def aggregates_tree
  @aggregates_tree
end

#base_klassesObject (readonly)

Returns the value of attribute base_klasses.



8
9
10
# File 'lib/lore/model/associations.rb', line 8

def base_klasses
  @base_klasses
end

#base_klasses_treeObject (readonly)

Returns the value of attribute base_klasses_tree.



14
15
16
# File 'lib/lore/model/associations.rb', line 14

def base_klasses_tree
  @base_klasses_tree
end

#belongs_toObject (readonly)

Returns the value of attribute belongs_to.



11
12
13
# File 'lib/lore/model/associations.rb', line 11

def belongs_to
  @belongs_to
end

#concrete_modelsObject (readonly)

Returns the value of attribute concrete_models.



46
47
48
# File 'lib/lore/model/associations.rb', line 46

def concrete_models
  @concrete_models
end

#foreign_keysObject (readonly)

Returns the value of attribute foreign_keys.



6
7
8
# File 'lib/lore/model/associations.rb', line 6

def foreign_keys
  @foreign_keys
end

#has_aObject (readonly)

Returns the value of attribute has_a.



9
10
11
# File 'lib/lore/model/associations.rb', line 9

def has_a
  @has_a
end

#has_nObject (readonly)

Returns the value of attribute has_n.



10
11
12
# File 'lib/lore/model/associations.rb', line 10

def has_n
  @has_n
end

#pkey_value_lookupObject (readonly)

Returns mapping rules from own foreign key values to foreign primary key values. Supports composed foreign keys. Example:

{ 
  'public.vehicle'   => [ :vehicle_id ], 
  'public.motorizes' => [ :motorized_id ] 
}
-->
# Mapping is:  [ <table>, <own key names>, <foreign pkey name> ]
[ 
  'public.vehicle',   [ :vehicle_id ], [ :id ], 
  'public.motorized', [ :motorizes_id ], [ :id ], 
]

Note that this is an array, not a Hash, and entries are ordered by join order. (Which is important as arrays are ordered, opposed to Hashes in Ruby 1.8)

For in-depth understanding, see Model_Instance#get_primary_key_value_map



36
37
38
# File 'lib/lore/model/associations.rb', line 36

def pkey_value_lookup
  @pkey_value_lookup
end

#polymorphicsObject (readonly)

Returns polymorphic base classes as map

{ table => polymorphic_attribute }

Example:

{ 'public.asset' => :concrete_asset_model }


44
45
46
# File 'lib/lore/model/associations.rb', line 44

def polymorphics
  @polymorphics
end

#primary_keysObject (readonly)

Returns the value of attribute primary_keys.



7
8
9
# File 'lib/lore/model/associations.rb', line 7

def primary_keys
  @primary_keys
end

Instance Method Details

#add_aggregate_model(model, *keys) ⇒ Object

Add another model as aggregate model. Leads to inheritance of fields, primary keys, joins etc.

Used by Model.aggregates Other_Model



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/lore/model/associations.rb', line 131

def add_aggregate_model(model, *keys)
# {{{
  add_foreign_key_to(model, *keys)
  @aggregate_klasses[model.table_name] = [ model, *keys ]
  @aggregates_tree[model.table_name]   = model.__associations__.aggregates_tree
  # Required attributes of aggregated models are not 
  # required in this model, as aggregated models are 
  # referenced by their pkey only and have to exist 
  # in DB already. 
  # Thus, the foreign key to an aggregated model is
  # required only: 
  keys.flatten.each { |attribute|
    @accessor.__attributes__.set_required(attribute)
  }
  inherit(model)
end

#add_base_model(model, *keys) ⇒ Object

Add another model as base model. Leads to inheritance of fields, primary keys, joins etc.

Used by Model.is_a? Other_Model



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/lore/model/associations.rb', line 97

def add_base_model(model, *keys)
# {{{
  add_foreign_key_to(model, *keys)
  @base_klasses[model.table_name]      = [ model, *keys ]
  @base_klasses_tree[model.table_name] = model.__associations__.base_klasses_tree
  @aggregates_tree[model.table_name]   = model.__associations__.aggregates_tree
  keys.flatten.each { |attribute|
    @accessor.__attributes__.set_implicit(@accessor.table_name, attribute)
  }
  @primary_keys.update(model.__associations__.primary_keys)
  @pkey_value_lookup += model.__associations__.pkey_value_lookup
  @pkey_value_lookup << [ model.table_name, 
                          keys.flatten, 
                          model.__associations__.primary_keys[model.table_name] ]
  if model.is_polymorphic? then
    @polymorphics[model.table_name] = model.polymorphic_attribute
    model.__associations__.add_concrete_model(@accessor)
  end
  inherit(model)
end

#add_belongs_to(model, *keys) ⇒ Object

For wheel.get_car()



211
212
213
214
# File 'lib/lore/model/associations.rb', line 211

def add_belongs_to(model, *keys)
  add_foreign_key_to(model, *keys)
  @belongs_to[@accessor.table_name] = model
end

#add_concrete_model(model) ⇒ Object

For polymorphic models only. Adds a concrete model class for a polymorphic model.



121
122
123
# File 'lib/lore/model/associations.rb', line 121

def add_concrete_model(model)
  @concrete_models << model
end

#add_has_a(model, *keys) ⇒ Object

For cat.get_wheel()



199
200
201
202
# File 'lib/lore/model/associations.rb', line 199

def add_has_a(model, *keys)
  add_foreign_key_to(model, *keys)
  @has_a[@accessor.table_name] = model
end

#add_has_n(model, *keys) ⇒ Object

For cat.get_wheel_set()



205
206
207
208
# File 'lib/lore/model/associations.rb', line 205

def add_has_n(model, *keys)
  add_foreign_key_to(model, *keys)
  @has_n[@accessor.table_name] = model
end

#add_primary_key(attribute, sequence_name = nil) ⇒ Object



86
87
88
89
# File 'lib/lore/model/associations.rb', line 86

def add_primary_key(attribute, sequence_name=nil)
  @primary_keys[@accessor.table_name] = [] unless @primary_keys[@accessor.table_name]
  @primary_keys[@accessor.table_name] << attribute
end

#has_aggregate_model?(model) ⇒ Boolean

Recursively checks if another model is aggregated by this model, either directly (foreign key is in own table) or via inheritance (foreign key is in joined table).

Returns:

  • (Boolean)


157
158
159
160
161
162
163
164
165
166
167
# File 'lib/lore/model/associations.rb', line 157

def has_aggregate_model?(model)
# {{{
  @aggregate_klasses.each_pair { |table,map|
    aggr_model = map.first
    if aggr_model == model || 
       aggr_model.__associations__.has_aggregate_model?(model) then
      return true 
    end
  }
  return false
end

#has_base_model?(model) ⇒ Boolean

Recursively checks if another model is a base model

of this model, either directly (foreign key is in own table) or via inheritance (foreign key is in joined table).

Returns:

  • (Boolean)


173
174
175
176
177
178
179
180
181
182
183
# File 'lib/lore/model/associations.rb', line 173

def has_base_model?(model)
# {{{
  @base_klasses.each_pair { |table,map|
    aggr_model = map.first
    if aggr_model == model || 
       aggr_model.__associations__.has_base_model?(model) then
      return true 
    end
  }
  return false
end

#has_joined_model?(model) ⇒ Boolean

Recursively checks if another model is joined

by this model (aggregated or as base model), either directly (foreign key is in own table) or via inheritance (foreign key is in joined table).

Returns:

  • (Boolean)


189
190
191
# File 'lib/lore/model/associations.rb', line 189

def has_joined_model?(model)
  has_base_model?(model) || has_aggregated_model?(model)
end

#inherit(base_model) ⇒ Object



216
217
218
219
220
221
# File 'lib/lore/model/associations.rb', line 216

def inherit(base_model)
  parent_associations = base_model.__associations__
  @has_a.update(parent_associations.has_a)
  @has_n.update(parent_associations.has_n)
  @belongs_to.update(parent_associations.belongs_to)
end

#joined_modelsObject Also known as: joined_klasses

}}}



148
149
150
# File 'lib/lore/model/associations.rb', line 148

def joined_models()
  @joined_models || @joined_models = @aggregate_klasses.dup.update(@base_klasses)
end

#joinsObject



194
195
196
# File 'lib/lore/model/associations.rb', line 194

def joins()
  @joins || @joins = @aggregates_tree.dup.update(@base_klasses_tree)
end