Module: ModelRecord

Included in:
ActiveOrient::Model
Defined in:
lib/model/the_record.rb

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args) ⇒ Object

How to handle other calls

  • if attribute is specified, display it

  • if attribute= is provided, assign to the known property or create a new one

Example:

ORD.create_class :a
a = A.new
a.test= 'test'  # <--- attribute: 'test=', argument: 'test'
a.test	  # <--- attribute: 'test' --> fetch attributes[:test]

Assignments are performed only in ruby-space.

Automatic database-updates are deactivated for now



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/model/the_record.rb', line 273

def method_missing *args
  # if the first entry of the parameter-array is a known attribute
  # proceed with the assignment
  if args.size == 1
     attributes[args.first.to_sym]  # return the attribute-value
  elsif args[0][-1] == "=" 
    if args.size == 2
#	if rid.rid? 
#	  update set:{ args[0][0..-2] => args.last }
#	else
 self.attributes[ args[0][0..-2]  ] = args.last
#	end
    else
 self.attributes[ args[0][0..-2]  ] = args[1 .. -1]
#	update set: {args[0][0..-2] => args[1 .. -1] } if rid.rid?
    end
  else
    raise NameError, "Unknown method call #{args.first.to_s}", caller
  end
end

Class Method Details

.classnameObject

Returns just the name of the Class



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

def self.classname  # :nodoc:
  self.class.to_s.split(':')[-1]
end

Instance Method Details

#deleteObject

Removes the Model-Instance from the database.

It is overloaded in Vertex and Edge.



124
125
126
# File 'lib/model/the_record.rb', line 124

def delete 
  orientdb.delete_record  self 
end

#find(attributes = {}) ⇒ Object

Fires a »where-Query» to the database starting with the current model-record.

Attributes:

  • a string ( obj.find “in().out().some_attribute >3” )

  • a hash ( obj.find ‘some_embedded_obj.name’ => ‘test’ )

  • an array

Returns the result-set, ie. a Query-Object which contains links to the addressed records.



94
95
96
97
# File 'lib/model/the_record.rb', line 94

def find attributes =  {}
  q = OrientSupport::OrientQuery.new from: self, where: attributes
  query q
end

#from_orientObject

GET #############



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

def from_orient # :nodoc:
  self
end

#has_property?(property) ⇒ Boolean

flag whether a property exists on the Record-level

Returns:

  • (Boolean)


21
22
23
# File 'lib/model/the_record.rb', line 21

def has_property? property
  attributes.keys.include? property.to_sym
end

#is_edge?Boolean

An Edge is defined

* when inherent from the superclass »E» (formal definition)
* if it has an in- and an out property

Actually we just check the second term as we trust the constructor to work properly

Returns:

  • (Boolean)


253
254
255
# File 'lib/model/the_record.rb', line 253

def is_edge? # :nodoc:
  attributes.keys.include?('in') && attributes.keys.include?('out')
end

#propertiesObject



25
26
27
# File 'lib/model/the_record.rb', line 25

def properties 
	{ "@type" => "d", "@class" => self.[:class] }.merge attributes
end

#query(**args) ⇒ Object

returns a OrientSupport::OrientQuery



53
54
55
# File 'lib/model/the_record.rb', line 53

def query **args
	OrientSupport::OrientQuery.new( **{ from: self}.merge(args))
end

#reload!Object



237
238
239
240
# File 'lib/model/the_record.rb', line 237

def reload! 
  transfer_content from: db.get_record(rid) 
self
end

#ridObject

Obtain the RID of the Record (format: 00:00)



33
34
35
36
37
38
39
# File 'lib/model/the_record.rb', line 33

def rid
  begin
    "#{@metadata[:cluster]}:#{@metadata[:record]}"
  rescue
    "0:0"
  end
end

#rridObject Also known as: to_orient

The extended representation of RID (format: #00:00 )



43
44
45
# File 'lib/model/the_record.rb', line 43

def rrid
  "#" + rid
end

#saveObject

Saves the record by calling update or creating the record

ORD.create_class :a
a =  A.new
a.test = 'test'
a.save

a =  A.first
a.test = 'test'
a.save


228
229
230
231
232
233
234
235
# File 'lib/model/the_record.rb', line 228

def save
	transfer_content from:  if rid.rid?
														db.update self, attributes, version
													else
														db.create_record  self, attributes: attributes, cache: false 
													end
	ActiveOrient::Base.store_rid self
end

#to_orObject



48
49
50
# File 'lib/model/the_record.rb', line 48

def to_or
  rid.rid? ?  rrid : "{ #{embedded} }"
end

#to_sObject

RECORD FUNCTIONS ###############



4
5
6
# File 'lib/model/the_record.rb', line 4

def to_s
	to_human
end

#transfer_content(from:) ⇒ Object

protected



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/model/the_record.rb', line 296

def transfer_content  from:
# »from« can be either 
# a model record (in case of  create-record, get_record) or
# a hash containing {"@type"=>"d", "@rid"=>"#xx:yy", "@version"=>n, "@class"=>'a_classname'} 
# and a list of updated properties (in case of db.update). Then  update the version field and the 
# attributes.
	return nil if from.nil?	
	if from.is_a? ActiveOrient::Model
     @metadata = from.
     self.attributes =  from.attributes
	else
		self.version =  from['@version']
		# throw away from["@..."] and convert keys to symbols, finally merge to attributes
		@attributes.merge! Hash[ from.delete_if{|k,_| k =~ /^@/}.map{|k,v| [k.to_sym, v.from_orient]}]
	end
	self  # return the modified object
end

#update(set: {}, remove: {}, **args) ⇒ Object

Convenient update of the dataset

A) Using PATCH

Previously changed attributes are saved to the database.

Using the optional »:set:« argument ad-hoc attributes can be defined

V.create_class :contracts
obj = Contracts.first
obj.name =  'new_name'
obj.update set: { yesterdays_event: 35 }

updates both, the »name« and the »yesterdays_event«-properties

B) Manual Modus

Update accepts a Block. The contents are parsed to »set«. Manual conversion of ruby-objects to the database-input format is necessary

i.e. hct is an Array of ActiveOrient::Model-records. then obj.update { “positions = #ModelRecord.hcthct.to_or ” } translates to update #83:64 set positions = [#90:18, #91:18, #92:18] return after @this and returns the modified record.

The manual modus accepts the keyword »remove«.

obj.update(remove: true) { “positions = #ModelRecord.hcthct.firsthct.first.to_or ” } translates to update #83:64 remove positions = #90:18 return after @this

This can be achieved by

obj.positions

If the update process is not successful, nil is returned



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/model/the_record.rb', line 171

def update set: {}, remove: {}, **args
	logger.progname = 'ActiveOrient::Model#Update'
	#	query( kind: update,  )
	if block_given?			# calling vs. a block is used internally
		# to remove an Item from lists and sets call update(remove: true){ query }
		set_or_remove =  args[:remove].present? ? "remove" : "set"
		#transfer_content from: 	 
		updated_record = 	db.execute{  "update #{rrid}  #{ yield }  return after $current" } &.first
		transfer_content from: updated_record  if updated_record.present?
	else
		set = if remove.present?
						{ remove: remove.merge!( args) }
					elsif set.present?
						 set.merge!( args) 
					else
						 args 
					end
		#	set.merge updated_at: DateTime.now
		if rid.rid?
			q= query.kind(:update)
			if remove.present?
				q.remove(remove)
			else
				q.set(set)
			end
		transfer_content from: 	q.execute(reduce: true){ |y| y[:$current].reload! }
		else  # new record
			 self.attributes.merge!  set
			 save
		end
	end
end

#update_attribute(the_attribute, the_value) ⇒ Object

mocking active record



205
206
207
# File 'lib/model/the_record.rb', line 205

def update_attribute the_attribute, the_value # :nodoc:
  update the_attribute => the_value.to_or
end

#update_attributes(**args) ⇒ Object

:nodoc:



209
210
211
# File 'lib/model/the_record.rb', line 209

def update_attributes **args    # :nodoc:
  update  args
end

#versionObject

Get the version of the object



100
101
102
103
104
105
106
# File 'lib/model/the_record.rb', line 100

def version  # :nodoc:
  if document.present?
    document.version
  else
    @metadata[:version]
  end
end