Module: Lore::Model_Instance
- Includes:
- Polymorphic_Instance_Methods
- Included in:
- Table_Accessor
- Defined in:
- lib/lore/model/model_instance.rb
Overview
Used as mixin for Table_Accessor. This module holds methods provided by Table_Accessor instances.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
See ==.
-
#==(other) ⇒ Object
Returns true if instance points to same records as other instance.
-
#===(other) ⇒ Object
Returns true if instance points to same records as other instance, also compares non-key attribute values.
-
#[](clause) ⇒ Object
Explicit attribute request.
-
#abs_attr(klass = nil) ⇒ Object
Returns value hash of instance attributes of a given subtype like: .
-
#attr ⇒ Object
Returns value hash of instance attributes like: .
-
#attribute_values ⇒ Object
def.
-
#commit ⇒ Object
(also: #save)
Commit changes on Table_Accessor instance to DB.
-
#delete ⇒ Object
Delete this instance from DB.
-
#get_attribute_value_map ⇒ Object
Returns attribute values mapped to table names.
-
#get_attribute_values ⇒ Object
Returns all attribute values as hash.
- #get_label_string ⇒ Object
-
#get_primary_key_value_map ⇒ Object
Returns primary key values mapped to table names.
- #get_primary_key_values ⇒ Object
- #id ⇒ Object
-
#inspect ⇒ Object
def.
-
#is_cached_entity? ⇒ Boolean
Whether this instance has been loaded from cache or live from DB.
-
#key ⇒ Object
Returns primary key values of own table.
-
#marshal_dump ⇒ Object
Create a marshalled dump of this model instance.
-
#marshal_load(dump) ⇒ Object
Creates an instance of self from marshalled value set.
- #method_missing(meth, *args) ⇒ Object
- #obj_id ⇒ Object
-
#pkey ⇒ Object
Return primary key value.
- #pkeys ⇒ Object
-
#set_attribute_value(attrib_name, attrib_value) ⇒ Object
(also: #[]=)
Set value for given attribute, e.g.
-
#set_attribute_values(value_hash) ⇒ Object
def }}}.
- #table_accessor ⇒ Object
- #touch(attrib_name = nil) ⇒ Object
- #touched? ⇒ Boolean
- #untouch(attrib_name = nil) ⇒ Object
- #update_pkey_values ⇒ Object
- #update_values ⇒ Object
Methods included from Polymorphic_Instance_Methods
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
159 160 161 |
# File 'lib/lore/model/model_instance.rb', line 159 def method_missing(meth, *args) return @attribute_values_flat[meth] end |
Instance Method Details
#<=>(other) ⇒ Object
See ==
241 242 243 |
# File 'lib/lore/model/model_instance.rb', line 241 def <=>(other) return !(self.==(other)) end |
#==(other) ⇒ Object
Returns true if instance points to same records as other instance. Only compares primary key values.
216 217 218 219 |
# File 'lib/lore/model/model_instance.rb', line 216 def ==(other) return false if self.class.to_s != other.class.to_s return pkeys() == other.pkeys() end |
#===(other) ⇒ Object
Returns true if instance points to same records as other instance, also compares non-key attribute values.
236 237 238 239 |
# File 'lib/lore/model/model_instance.rb', line 236 def ===(other) return false unless (self == other) end |
#[](clause) ⇒ Object
Explicit attribute request. Example:
Car[Vehicle.name]
In case name is attribute field in Car and Vehicle.
210 211 212 |
# File 'lib/lore/model/model_instance.rb', line 210 def [](clause) abs_attr(clause) end |
#abs_attr(klass = nil) ⇒ Object
Returns value hash of instance attributes of a given subtype like:
{
'id' => 123,
'name' => 'example'
}
Common usage:
self.class.abs_attr(Klass_A)[:id] -> 123
297 298 299 300 301 302 303 304 305 |
# File 'lib/lore/model/model_instance.rb', line 297 def abs_attr(klass=nil) Lore.logger.warn { 'abs_attr() is deprecated' } klass = klass.to_s if klass.instance_of? Symbol return @attribute_values if klass.nil? return @attribute_values[klass.table_name] if klass.kind_of? Lore::Table_Accessor return @attribute_values[klass] if klass.instance_of? String return @attribute_values[klass.to_s.split('.')[0..1].join('.').to_s][klass.to_s.split('.').at(-1)] if klass.instance_of? Lore::Clause end |
#attr ⇒ Object
Returns value hash of instance attributes like:
{
'schema.table.id' => 123,
'schema.atable.name' => 'example'
}
Common usage:
table_instance.attr[:id] -> 123
But it is recommended to use
table_instance.id -> 123
272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/lore/model/model_instance.rb', line 272 def attr return @attribute_values_flat if @flat_attr.nil? then @flat_attr = Attribute_Hash.new @attribute_values.each_pair { |table, attribs| attribs.each_pair { |attrib_name, value| @flat_attr[attrib_name] = value unless value.nil? } } end @flat_attr end |
#attribute_values ⇒ Object
def
307 308 309 310 |
# File 'lib/lore/model/model_instance.rb', line 307 def attribute_values @attribute_values ||= self.class.distribute_attrib_values(@attribute_values_flat) @attribute_values end |
#commit ⇒ Object Also known as: save
Commit changes on Table_Accessor instance to DB. Results in one or more SQL update calls.
Common usage:
unit.name = 'changed'
unit.commit()
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/lore/model/model_instance.rb', line 320 def commit # {{{ return unless @touched Lore.logger.debug { "Updating #{self.to_s}. " } Lore.logger.debug { "Touched values are: #{@touched_fields.inspect}" } # TODO: Optimize this! @attribute_values = self.class.distribute_attrib_values(@attribute_values_flat) foreign_pkey_values = false @update_values = {} @update_pkey_values = {} @attribute_values.each_pair { |table,attributes| @touched_fields.each { |name| value = @attribute_values[table][name] filter = self.class.__filters__.input_filters[name] value = filter.call(value) if filter if attributes[name] then update_values[table] ||= {} @update_values[table][name] = value end } foreign_pkey_values = get_primary_key_value_map[table] @update_pkey_values[table] = foreign_pkey_values if foreign_pkey_values } Validation::Parameter_Validator.validate_update(self.class, update_values) self.class.before_commit(self) self.class.__update_strategy__.perform_update(self) self.class.after_commit(self) @touched = false end |
#delete ⇒ Object
Delete this instance from DB. Common usage:
unit = Some_Table_Accessor.select { ... }.first
unit.delete
Calls hooks Table_Accessor.before_instance_delete(self) and Table_Accessor.after_instance_delete(self).
366 367 368 369 370 371 372 373 |
# File 'lib/lore/model/model_instance.rb', line 366 def delete # Called before entity_instance.delete self.class.before_instance_delete(self) self.class.__delete_strategy__.perform_delete(@attribute_values_flat) # Called after entity_instance.delete self.class.after_instance_delete(self) end |
#get_attribute_value_map ⇒ Object
Returns attribute values mapped to table names.
251 252 253 254 255 |
# File 'lib/lore/model/model_instance.rb', line 251 def get_attribute_value_map return @attribute_values if @attribute_values @attribute_values = self.class.distribute_attrib_values(@attribute_values_flat) return @attribute_values end |
#get_attribute_values ⇒ Object
Returns all attribute values as hash.
246 247 248 |
# File 'lib/lore/model/model_instance.rb', line 246 def get_attribute_values() # :nodoc: @attribute_values_flat end |
#get_label_string ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/lore/model/model_instance.rb', line 128 def get_label_string if !@label_string || @touched then value = '' self.class.get_labels.each { |label_attrib| label_parts = label_attrib.split('.') value << @attribute_values[label_parts[0..1].join('.')][label_parts[2]].to_s + ' ' } value = '[no label given]' if value == '' @label_string = value end return @label_string end |
#get_primary_key_value_map ⇒ Object
Returns primary key values mapped to table names.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/lore/model/model_instance.rb', line 91 def get_primary_key_value_map # {{{ return @primary_key_value_map if (@primary_key_value_map && !@touched) accessor = self.class base_models = accessor.__associations__.base_klasses() table_name = accessor.table_name pkey_fields = accessor.get_primary_keys if !pkey_fields[table_name] then raise ::Exception.new("Unable to resolve pkey fields for #{self.class.to_s}. Known fields are: #{pkey_fields.inspect}") end @primary_key_value_map = { table_name => {} } pkey_fields[table_name].each { |own_pkey| @primary_key_value_map[table_name][own_pkey] = @attribute_values_flat[own_pkey] } # Map own foreign key values back to foreign primary key # values. This is necessary as joined primary key field names are # shadowed. accessor.__associations__.pkey_value_lookup.each { |mapping| foreign_pkeys = {} mapping.at(1).each_with_index { |fkey,idx| value = @attribute_values_flat[fkey] foreign_pkeys[mapping.at(2).at(idx)] = value } @primary_key_value_map[mapping.at(0)] = foreign_pkeys } return @primary_key_value_map end |
#get_primary_key_values ⇒ Object
80 81 82 83 84 85 86 87 88 |
# File 'lib/lore/model/model_instance.rb', line 80 def get_primary_key_values return @primary_key_values if @primary_key_values keys = self.class.get_primary_keys[self.class.table_name] @primary_key_values = keys.map { |pkey| @attribute_values_flat[pkey] } @primary_key_values end |
#id ⇒ Object
164 165 166 |
# File 'lib/lore/model/model_instance.rb', line 164 def id @attribute_values_flat[:id] || obj_id end |
#inspect ⇒ Object
def
375 376 377 378 |
# File 'lib/lore/model/model_instance.rb', line 375 def inspect # {{{ 'Lore::Table_Accessor entity: ' << @attribute_values_flat.inspect end |
#is_cached_entity? ⇒ Boolean
Whether this instance has been loaded from cache or live from DB.
75 76 77 78 |
# File 'lib/lore/model/model_instance.rb', line 75 def is_cached_entity? # Set in initialize via marshal_load @loaded_from_cache end |
#key ⇒ Object
Returns primary key values of own table
124 125 126 |
# File 'lib/lore/model/model_instance.rb', line 124 def key get_primary_key_value_map[self.class.table_name] end |
#marshal_dump ⇒ Object
Create a marshalled dump of this model instance. Returns attribute values as The only difference between model instances is their value set.
60 61 62 63 64 65 66 |
# File 'lib/lore/model/model_instance.rb', line 60 def marshal_dump { :klass => self.class.to_s, :values => @attribute_values_flat, :joined => @joined_models } end |
#marshal_load(dump) ⇒ Object
Creates an instance of self from marshalled value set.
69 70 71 |
# File 'lib/lore/model/model_instance.rb', line 69 def marshal_load(dump) return initialize(dump[:values], dump[:joined], :cached) end |
#obj_id ⇒ Object
163 |
# File 'lib/lore/model/model_instance.rb', line 163 alias :obj_id :id |
#pkey ⇒ Object
Return primary key value. In case primary key is composed, return it as array.
222 223 224 225 226 227 |
# File 'lib/lore/model/model_instance.rb', line 222 def pkey table = self.class.table_name key = get_primary_key_values return key.first if key.length < 2 return key end |
#pkeys ⇒ Object
229 230 231 232 |
# File 'lib/lore/model/model_instance.rb', line 229 def pkeys table = self.class.table_name return get_primary_key_values end |
#set_attribute_value(attrib_name, attrib_value) ⇒ Object Also known as: []=
Set value for given attribute, e.g. for later commit. It is recommended to use random access assignment instead:
instance.set_attribute_value(:name, 'Wombat')
is same as
instance[:name] = 'Wombat'
175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/lore/model/model_instance.rb', line 175 def set_attribute_value(attrib_name, attrib_value) # {{{ if @input_filters && (@input_filters.has_key?(attrib_name.intern)) then attrib_value = @input_filters[attrib_name.intern].call(attrib_value) end # touch(attrib_name) @touched = true @touched_fields ||= [] @touched_fields << attrib_name if attrib_name @attribute_values_flat[attrib_name.to_sym] = attrib_value end |
#set_attribute_values(value_hash) ⇒ Object
def }}}
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/lore/model/model_instance.rb', line 190 def set_attribute_values(value_hash) value_hash.each_pair { |attrib_name,value| if @input_filters && @input_filters.has_key?(attrib_name.intern) then value_hash[attrib_name] = @input_filters[attrib_name.intern].call(attrib_value) end @attribute_values_flat[attrib_name.to_sym] = attrib_value @touched_fields << attrib_name.intern } touch end |
#table_accessor ⇒ Object
46 47 48 |
# File 'lib/lore/model/model_instance.rb', line 46 def table_accessor self.class end |
#touch(attrib_name = nil) ⇒ Object
146 147 148 149 150 151 152 |
# File 'lib/lore/model/model_instance.rb', line 146 def touch(attrib_name=nil) @touched = true @touched_fields ||= [] @touched_fields << attrib_name if attrib_name @primary_key_value_map = false @primary_key_values = false end |
#touched? ⇒ Boolean
142 143 144 |
# File 'lib/lore/model/model_instance.rb', line 142 def touched? (@touched === true) end |
#untouch(attrib_name = nil) ⇒ Object
154 155 156 157 |
# File 'lib/lore/model/model_instance.rb', line 154 def untouch(attrib_name=nil) @touched = false @touched_fields.delete(attrib_name) if attrib_name end |
#update_pkey_values ⇒ Object
53 54 55 |
# File 'lib/lore/model/model_instance.rb', line 53 def update_pkey_values @update_pkey_values end |
#update_values ⇒ Object
50 51 52 |
# File 'lib/lore/model/model_instance.rb', line 50 def update_values @update_values end |