Class: Lafcadio::DomainObjectField

Inherits:
ObjectField show all
Defined in:
lib/lafcadio/objectField.rb,
lib/lafcadio/test.rb

Overview

A DomainObjectField is used to link from one domain class to another. To add such an association in a class definition, call DomainObject.domain_object:

class Invoice < Lafcadio::DomainObject
  domain_object Client
end

By default, the field name is assumed to be the same as the class name, only lower-cased and camel-case.

class LineItem < Lafcadio::DomainObject
  domain_object Product         # field name 'product'
  domain_object CatalogOrder    # field name 'catalog_order'
end

The field name can be explicitly set as the 2nd argument of DomainObject.domain_object.

class Message < Lafcadio::DomainObject
  domain_object User, 'sender'
  domain_object User, 'recipient'
end

Setting delete_cascade to true means that if the domain object being associated to is deleted, this domain object will also be deleted.

class Invoice < Lafcadio::DomainObject
  domain_object Client, 'client', { 'delete_cascade' => true }
end
cli = Client.new( 'name' => 'big company' ).commit
inv = Invoice.new( 'client' => cli ).commit
cli.delete!
inv_prime = Invoice[inv.pk_id] # => will raise DomainObjectNotFoundError

Direct Known Subclasses

SubsetDomainObjectField

Instance Attribute Summary collapse

Attributes inherited from ObjectField

#db_field_name, #domain_class, #mock_value, #name, #not_nil

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ObjectField

#<=>, #bind_write?, create_from_xml, #db_column, #db_will_automatically_write?, #prev_value, #process_before_verify, value_type, #verify

Constructor Details

#initialize(domain_class, linked_type, name = nil, delete_cascade = false) ⇒ DomainObjectField

Returns a new instance of DomainObjectField.



347
348
349
350
351
352
# File 'lib/lafcadio/objectField.rb', line 347

def initialize( domain_class, linked_type, name = nil,
                delete_cascade = false ) #:nodoc:
	name = self.class.auto_name( linked_type ) unless name
	super( domain_class, name )
	( @linked_type, @delete_cascade ) = linked_type, delete_cascade
end

Instance Attribute Details

#delete_cascadeObject

Returns the value of attribute delete_cascade.



345
346
347
# File 'lib/lafcadio/objectField.rb', line 345

def delete_cascade
  @delete_cascade
end

#linked_typeObject (readonly)

Returns the value of attribute linked_type.



344
345
346
# File 'lib/lafcadio/objectField.rb', line 344

def linked_type
  @linked_type
end

Class Method Details

.auto_name(linked_type) ⇒ Object

:nodoc:



318
319
320
# File 'lib/lafcadio/objectField.rb', line 318

def self.auto_name( linked_type ) #:nodoc:
	linked_type.basename.camel_case_to_underscore
end

.create_with_args(domain_class, parameters) ⇒ Object

:nodoc:



322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/lafcadio/objectField.rb', line 322

def self.create_with_args( domain_class, parameters ) #:nodoc:
	linked_type = parameters['linked_type']
	instance = self.new(
		domain_class, linked_type,
		parameters['name'] || auto_name( linked_type ),
		parameters['delete_cascade']
	)
	if parameters['db_field_name']
		instance.db_field_name = parameters['db_field_name']
	end
	instance
end

.creation_parameters(fieldElt) ⇒ Object

:nodoc:



335
336
337
338
339
340
341
342
# File 'lib/lafcadio/objectField.rb', line 335

def self.creation_parameters( fieldElt ) #:nodoc:
	parameters = super( fieldElt )
	linked_typeStr = fieldElt.attributes['linked_type']
	parameters['linked_type'] = Class.by_name linked_typeStr
	parameters['delete_cascade'] = 
			( fieldElt.attributes['delete_cascade'] == 'y' )
	parameters
end

Instance Method Details

#default_mock_valueObject

:nodoc:



299
300
301
# File 'lib/lafcadio/test.rb', line 299

def default_mock_value #:nodoc:
	DomainObjectProxy.new( linked_type, 1 )
end

#value_for_sql(value) ⇒ Object

:nodoc:



354
355
356
357
358
359
360
361
362
363
364
# File 'lib/lafcadio/objectField.rb', line 354

def value_for_sql(value) #:nodoc:
	if value.nil?
		"null"
	elsif value.pk_id
		value.pk_id
	else
		raise(
			DomainObjectInitError, "Can't commit #{name} without pk_id", caller
		)
	end
end

#value_from_sql(string) ⇒ Object

:nodoc:



366
367
368
# File 'lib/lafcadio/objectField.rb', line 366

def value_from_sql(string) #:nodoc:
	string ? DomainObjectProxy.new(@linked_type, string.to_i) : nil
end

#verify_non_nil_value(value, pk_id) ⇒ Object

:nodoc:



370
371
372
373
374
375
376
377
378
379
380
# File 'lib/lafcadio/objectField.rb', line 370

def verify_non_nil_value(value, pk_id) #:nodoc:
	super
	if @linked_type != @domain_class && pk_id
		subsetDomainObjectField = @linked_type.class_fields.find { |field|
			field.is_a?( SubsetDomainObjectField ) && field.subset_field == @name
		}
		if subsetDomainObjectField
			verify_subset_link_field( subsetDomainObjectField, pk_id )
		end
	end
end

:nodoc:



382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/lafcadio/objectField.rb', line 382

def verify_subset_link_field( subsetDomainObjectField, pk_id ) #:nodoc:
	begin
		prevObjLinkedTo = domain_class[pk_id].send(name)
		possiblyMyObj = prevObjLinkedTo.send subsetDomainObjectField.name
		if possiblyMyObj && possiblyMyObj.pk_id == pk_id
			cantChangeMsg = "You can't change that."
			raise FieldValueError, cantChangeMsg, caller
		end
	rescue DomainObjectNotFoundError
		# no previous value, so nothing to check for
	end
end