Class: Lafcadio::DomainObject
- Inherits:
-
Object
- Object
- Lafcadio::DomainObject
- Includes:
- DomainComparable
- Defined in:
- lib/lafcadio/domain.rb,
lib/lafcadio/test.rb
Overview
)
pk_id and committing
Lafcadio requires that each table has a numeric primary key. It assumes that this key is named pk_id
in the database, though that can be overridden.
When you create a domain object by calling DomainObject.new, you should not assign a pk_id
to the new instance. The pk_id will automatically be set when you commit the object by calling DomainObject#commit.
However, you may want to manually set pk_id
when setting up a test case, so you can ensure that a domain object has a given primary key.
Naming assumptions, and how to override them
By default, Lafcadio assumes that every domain object is indexed by the field pk_id
in the database schema. If you’re dealing with a table that uses a different field name, call DomainObject.sql_primary_key_name. However, you will always use pk_id
in your Ruby code.
Lafcadio assumes that a domain class corresponds to a table whose name is the pluralized, lower-case, underscored version of the class name. A User class is assumed to be stored in a “users” table, while a ProductCategory class is assumed to be stored in a “product_categories” table. Call DomainObject.table_name to override this behavior.
class LegacyThing < Lafcadio::DomainObject
string 'some_field'
sql_primary_key_name 'some_legacy_id'
table_name 'some_legacy_table'
end
thing = LegacyThing[9909]
thing.pk_id # => 9909
Inheritance
Domain classes can inherit from other domain classes; they have all the fields of any concrete superclasses plus any new fields defined for themselves. You can use normal inheritance to define this:
class User < Lafcadio::DomainObject
...
end
class Administrator < User
...
end
Lafcadio assumes that each concrete class has a corresponding table, and that each table has a pk_id
field that is used to match rows between different levels.
Direct Known Subclasses
Defined Under Namespace
Classes: ReadOnlyHash, SubclassRecord
Constant Summary collapse
- @@subclass_records =
Hash.new do |h, k| h[k] = SubclassRecord.new( k ); end
- @@default_mock_available =
Hash.new true
- @@default_arg_directives =
Hash.new { |hash, a_class| default_args = {} a_class.all_fields.each do |field| default_args[field.name] = field.default_mock_value end hash[a_class] = default_args }
Instance Attribute Summary collapse
-
#delete ⇒ Object
Returns the value of attribute delete.
-
#field_values ⇒ Object
writeonly
Sets the attribute field_values.
-
#fields_set ⇒ Object
writeonly
Sets the attribute fields_set.
-
#last_commit_type ⇒ Object
Returns the value of attribute last_commit_type.
Class Method Summary collapse
-
.[](pk_id) ⇒ Object
Shortcut method for retrieving one domain object.
-
.abstract_subclass?(a_class) ⇒ Boolean
:nodoc:.
-
.abstract_subclasses ⇒ Object
:nodoc:.
-
.all(opts = {}) ⇒ Object
Returns every committed instance of the domain class.
-
.all_fields ⇒ Object
:nodoc:.
-
.class_field(fieldName) ⇒ Object
:nodoc:.
-
.class_fields ⇒ Object
:nodoc:.
-
.commit_mock(args, caller = nil) ⇒ Object
:nodoc:.
-
.create_field(field_class, *args) ⇒ Object
:nodoc:.
-
.create_field_att_hash(field_class, *args) ⇒ Object
:nodoc:.
-
.create_fields(field_class, *args) ⇒ Object
:nodoc:.
-
.custom_mock(custom_args = nil) ⇒ Object
Commits and returns a custom mock object of the given domain class.
-
.default_args ⇒ Object
Returns a hash of default arguments for mock instances of this domain class.
-
.default_field_setup_hash(field_class, hash) ⇒ Object
Sets a default setup hash for a field of a certain class.
-
.default_mock(calling_class = nil) ⇒ Object
Commits and returns a mock object of the given domain class.
-
.default_mock_available(is_avail) ⇒ Object
:nodoc:.
-
.dependent_classes ⇒ Object
:nodoc:.
-
.domain_class ⇒ Object
:nodoc:.
-
.domain_dirs ⇒ Object
:nodoc:.
-
.exist?(search_term, field_name = :pk_id) ⇒ Boolean
Tests whether a given domain object exists.
-
.field(fieldName) ⇒ Object
:nodoc:.
-
.first ⇒ Object
Returns the first domain object it can find.
-
.get(*args) ⇒ Object
This class method has a few uses, depending on how you use it.
-
.get_class_fields ⇒ Object
Returns an Array of ObjectField instances for this domain class, parsing them from XML if necessary.
-
.is_child_domain_class? ⇒ Boolean
:nodoc:.
-
.last ⇒ Object
Returns the last domain object.
-
.link_field(linked_domain_class) ⇒ Object
:nodoc:.
-
.maybe_call_default_mock(field, caller) ⇒ Object
:nodoc:.
-
.method_missing(methodId, *args) ⇒ Object
:nodoc:.
-
.method_missing_try_create_field(method_name, *args) ⇒ Object
:nodoc:.
-
.method_missing_try_create_fields(method_name, *args) ⇒ Object
:nodoc:.
-
.mock_value(field_sym, value) ⇒ Object
Sets the mock value for the given field.
-
.mock_values(hash) ⇒ Object
Sets the mock value for the fields in
hash
. -
.only ⇒ Object
Returns the only committed instance of the domain class.
- .postgres_pk_id_seq ⇒ Object
-
.require_domain_file(typeString) ⇒ Object
:nodoc:.
-
.self_and_concrete_superclasses ⇒ Object
:nodoc:.
-
.singleton_method_added(symbol) ⇒ Object
:nodoc:.
-
.sql_primary_key_name(set_db_field_name = nil) ⇒ Object
If
set_db_field_name
is nil, this will return the sql name of the primary key. -
.subclass_record ⇒ Object
:nodoc:.
-
.subclasses ⇒ Object
:nodoc:.
-
.table_name(set_table_name = nil) ⇒ Object
If
set_table_name
is nil, DomainObject.table_name will return the table name. -
.try_load_xml_parser ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#clone ⇒ Object
Returns a clone, with all of the fields copied.
-
#commit ⇒ Object
Commits this domain object to the database.
-
#delete! ⇒ Object
Deletes a domain object, committing the delete to the database immediately.
-
#domain_class ⇒ Object
Returns the subclass of DomainObject that this instance represents.
-
#field_value(field) ⇒ Object
:nodoc:.
-
#getter_field(methId) ⇒ Object
:nodoc:.
-
#initialize(field_hash) ⇒ DomainObject
constructor
field_hash
should contain key-value associations for the different fields of this domain class. -
#method_missing(methId, *args) ⇒ Object
:nodoc:.
-
#post_commit_trigger ⇒ Object
This template method is called after every commit.
-
#pre_commit_trigger ⇒ Object
This template method is called before every commit.
-
#preprocess_field_hash(fieldHash) ⇒ Object
:nodoc:.
-
#reset_original_values_hash(f = @field_values) ⇒ Object
:nodoc:.
-
#set_field_value(field, value) ⇒ Object
:nodoc:.
-
#setter_field(methId) ⇒ Object
:nodoc:.
-
#update!(changes) ⇒ Object
Updates a domain object and commits the changes to the database immediately.
-
#verify ⇒ Object
If you’re running against a MockObjectStore, this will verify each field and raise an error if there’s any invalid fields.
Methods included from DomainComparable
Constructor Details
#initialize(field_hash) ⇒ DomainObject
field_hash
should contain key-value associations for the different fields of this domain class. For example, instantiating a User class might look like:
User.new(
'firstNames' => 'John', 'lastName' => 'Doe',
'email' => '[email protected]', 'password' => 'l33t'
)
In normal usage any code you write that creates a domain object will not define the pk_id
field. The system assumes that a domain object with an undefined pk_id
has yet to be inserted into the database, and when you commit the domain object a pk_id
will automatically be assigned.
If you’re creating mock objects for unit tests, you can explicitly set the pk_id
to represent objects that already exist in the database.
680 681 682 683 684 685 686 687 |
# File 'lib/lafcadio/domain.rb', line 680 def initialize( field_hash ) field_hash = preprocess_field_hash field_hash @field_values = {} @fields_set = [] reset_original_values_hash @fieldHash check_fields = LafcadioConfig.new()['checkFields'] verify if %w( onInstantiate onAllStates ).include?( check_fields ) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(methId, *args) ⇒ Object
:nodoc:
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 |
# File 'lib/lafcadio/domain.rb', line 736 def method_missing( methId, *args ) #:nodoc: if ( field = setter_field( methId ) ) set_field_value( field, args.first ) elsif ( field = getter_field( methId ) ) field_value( field ) else object_store = ObjectStore.get_object_store if object_store.respond_to? methId args = [ self ].concat args object_store.send( methId, *args ) else super( methId, *args ) end end end |
Instance Attribute Details
#delete ⇒ Object
Returns the value of attribute delete.
661 662 663 |
# File 'lib/lafcadio/domain.rb', line 661 def delete @delete end |
#field_values=(value) ⇒ Object
Sets the attribute field_values
660 661 662 |
# File 'lib/lafcadio/domain.rb', line 660 def field_values=(value) @field_values = value end |
#fields_set=(value) ⇒ Object
Sets the attribute fields_set
660 661 662 |
# File 'lib/lafcadio/domain.rb', line 660 def fields_set=(value) @fields_set = value end |
#last_commit_type ⇒ Object
Returns the value of attribute last_commit_type.
660 661 662 |
# File 'lib/lafcadio/domain.rb', line 660 def last_commit_type @last_commit_type end |
Class Method Details
.[](pk_id) ⇒ Object
Shortcut method for retrieving one domain object.
User[7356] # => user with the pk_id 7536
288 |
# File 'lib/lafcadio/domain.rb', line 288 def self.[]( pk_id ); get( pk_id ); end |
.abstract_subclass?(a_class) ⇒ Boolean
:nodoc:
290 291 292 |
# File 'lib/lafcadio/domain.rb', line 290 def self.abstract_subclass?( a_class ) #:nodoc: abstract_subclasses.include? a_class end |
.abstract_subclasses ⇒ Object
:nodoc:
294 295 296 |
# File 'lib/lafcadio/domain.rb', line 294 def self.abstract_subclasses #:nodoc: [ MapObject ] end |
.all(opts = {}) ⇒ Object
Returns every committed instance of the domain class.
User.all # => all users
301 302 303 |
# File 'lib/lafcadio/domain.rb', line 301 def self.all( opts = {} ) ObjectStore.get_object_store.all( self, opts ) end |
.all_fields ⇒ Object
:nodoc:
305 306 307 308 309 |
# File 'lib/lafcadio/domain.rb', line 305 def self.all_fields # :nodoc: self_and_concrete_superclasses.map { |a_class| a_class.class_fields }.flatten end |
.class_field(fieldName) ⇒ Object
:nodoc:
311 312 313 |
# File 'lib/lafcadio/domain.rb', line 311 def self.class_field(fieldName) #:nodoc: self.class_fields.find { |field| field.name == fieldName.to_s } end |
.class_fields ⇒ Object
:nodoc:
315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/lafcadio/domain.rb', line 315 def self.class_fields #:nodoc: unless subclass_record.fields subclass_record.fields = self.get_class_fields subclass_record.fields.each do |class_field| begin undef_method class_field.name.to_sym rescue NameError # not defined globally or in an included Module, skip it end end end subclass_record.fields end |
.commit_mock(args, caller = nil) ⇒ Object
:nodoc:
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/lafcadio/test.rb', line 133 def self.commit_mock( args, caller = nil ) #:nodoc: dobj = self.new( args ) link_fields = all_fields.select { |field| field.is_a? DomainObjectField } link_fields.each do |field| val = dobj.send( field.name ) maybe_call_default_mock( field, caller ) if ( val and val.pk_id == 1 ) end dobj.commit dobj end |
.create_field(field_class, *args) ⇒ Object
:nodoc:
329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/lafcadio/domain.rb', line 329 def self.create_field( field_class, *args ) #:nodoc: subclass_record.maybe_init_fields att_hash = create_field_att_hash( field_class, *args ) field = field_class.create_with_args( self, att_hash ) unless class_field( field.name ) att_hash.each { |field_name, value| setter = field_name + '=' field.send( setter, value ) if field.respond_to?( setter ) } class_fields << field end end |
.create_field_att_hash(field_class, *args) ⇒ Object
:nodoc:
342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/lafcadio/domain.rb', line 342 def self.create_field_att_hash( field_class, *args ) #:nodoc: att_hash = args.last unless att_hash.is_a? Hash att_hash = subclass_record.default_field_setup_hash[field_class].clone end if field_class == DomainObjectField att_hash['linked_type'] = args.first att_hash['name'] = args[1] if args[1] and !args[1].is_a? Hash else att_hash['name'] = args.first.to_s end att_hash end |
.create_fields(field_class, *args) ⇒ Object
:nodoc:
356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/lafcadio/domain.rb', line 356 def self.create_fields( field_class, *args ) #:nodoc: arg = args.shift until args.empty? next_arg = args.shift if next_arg.is_a? String or next_arg.is_a? Symbol create_field( field_class, arg ) arg = next_arg else create_field( field_class, arg, next_arg ) arg = args.shift end end create_field( field_class, arg ) unless arg.nil? end |
.custom_mock(custom_args = nil) ⇒ Object
Commits and returns a custom mock object of the given domain class. All the field values are set to defaults, except for the fields passed in through custom_args
. This mock object will have a pk_id
greater than 1, and each successive call to DomainObject.custom_mock will return an object with a unique pk_id
.
This class method is only visible if you include lafcadio/test.rb
.
class User < Lafcadio::DomainObject
strings :fname, :lname, :email
end
u1 = User.custom_mock
u1.fname # => 'test text'
u1.lname # => 'test text'
u1.email # => 'test text'
u1.pk_id # => probably 2, guaranteed to be greater than 1
u2 = User.custom_mock( 'fname' => 'Francis', 'lname' => 'Hwang' )
u2.fname # => 'Francis'
u2.lname # => 'Hwang'
u2.email # => 'test text'
u2.pk_id # => probably 3, guaranteed to not be u1.pk_id and to be
# greater than 1
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/lafcadio/test.rb', line 167 def self.custom_mock( custom_args = nil ) dobj_args = default_args object_store = ObjectStore.get_object_store dbb = object_store.db_bridge dbb.set_next_pk_id( self, 2 ) if dbb.next_pk_id( self ) == 1 dobj_args['pk_id'] = nil if custom_args.is_a? Hash custom_args.each do |k, v| dobj_args[k.to_s] = v; end end commit_mock( dobj_args ) end |
.default_args ⇒ Object
Returns a hash of default arguments for mock instances of this domain class. DomainObject.default_mock uses exactly these arguments to create the default mock for a given domain class, and DomainObject.custom_mock overrides some of the field arguments based on its custom arguments.
By default this will retrieve simple values based on the field type:
-
BooleanField:
true
-
DateField: Date.today
-
DateTimeField: Time.now
-
DomainObjectField: The instance of the domain class with
pk_id
1 -
EmailField: “[email protected]”
-
FloatField: 0.0
-
IntegerField: 1
-
StringField: “test text”
-
TextListField: [ ‘a’, ‘b’, ‘c’ ]
You can override this method, if you like. However, it will probably be simpler just to call DomainObject.mock_value.
This class method is only visible if you include lafcadio/test.rb
.
200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/lafcadio/test.rb', line 200 def self.default_args default_args = {} @@default_arg_directives[self].each do |name, value_or_proc| if value_or_proc.is_a? Proc default_args[name] = value_or_proc.call else default_args[name] = value_or_proc end end default_args end |
.default_field_setup_hash(field_class, hash) ⇒ Object
Sets a default setup hash for a field of a certain class. Useful for mapping domain classes with lots of fields and unusual field configurations.
class LotsOfBooleans < Lafcadio::DomainObject
default_field_setup_hash(
Lafcadio::BooleanField, { 'enum_type' => :capital_yes_no }
)
booleans 'this', 'that', 'the_other', 'and_another_one',
'this_one_too'
end
382 383 384 |
# File 'lib/lafcadio/domain.rb', line 382 def self.default_field_setup_hash( field_class, hash ) subclass_record.default_field_setup_hash[field_class] = hash end |
.default_mock(calling_class = nil) ⇒ Object
Commits and returns a mock object of the given domain class. All the field values are set to defaults. This mock object will have a pk_id
of 1. Successive calls to DomainObject.default_mock will always return the same mock object.
This class method is only visible if you include lafcadio/test.rb
.
class User < Lafcadio::DomainObject
strings :fname, :lname, :email
end
u1 = User.default_mock
u1.fname # => 'test text'
u1.lname # => 'test text'
u1.email # => 'test text'
u1.pk_id # => 1
228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/lafcadio/test.rb', line 228 def self.default_mock( calling_class = nil ) if @@default_mock_available[self] begin dobj = ObjectStore.get_object_store.get( self, 1 ) dobj rescue DomainObjectNotFoundError dbb = ObjectStore.get_object_store.db_bridge dbb.set_next_pk_id( self, 1 ) if dbb.next_pk_id( self ) > 1 commit_mock( default_args, calling_class ) end else raise( TypeError, self.name + ".default_mock not allowed", caller ) end end |
.default_mock_available(is_avail) ⇒ Object
:nodoc:
243 244 245 |
# File 'lib/lafcadio/test.rb', line 243 def self.default_mock_available( is_avail ) #:nodoc: @@default_mock_available[self] = is_avail end |
.dependent_classes ⇒ Object
:nodoc:
386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/lafcadio/domain.rb', line 386 def self.dependent_classes #:nodoc: dependent_classes = {} DomainObject.subclasses.each { |aClass| if ( !abstract_subclass?( aClass ) and ( field = aClass.link_field( self ) ) ) dependent_classes[aClass] = field end } dependent_classes end |
.domain_class ⇒ Object
:nodoc:
399 400 401 |
# File 'lib/lafcadio/domain.rb', line 399 def self.domain_class #:nodoc: self end |
.domain_dirs ⇒ Object
:nodoc:
403 404 405 406 407 408 409 |
# File 'lib/lafcadio/domain.rb', line 403 def self.domain_dirs #:nodoc: if ( domainDirStr = LafcadioConfig.new['domainDirs'] ) domainDirStr.split(',') else [] end end |
.exist?(search_term, field_name = :pk_id) ⇒ Boolean
Tests whether a given domain object exists.
User.exist?( 8280 ) # => returns true iff there's a User 8280
User.exist?( 'Hwang', :lastName ) # => returns true iff there's a User
# with the last name 'Hwang'
416 417 418 419 420 421 |
# File 'lib/lafcadio/domain.rb', line 416 def self.exist?( search_term, field_name = :pk_id ) query = Query.infer( self ) { |dobj| dobj.send( field_name ).equals( search_term ) } !ObjectStore.get_object_store.query( query ).empty? end |
.field(fieldName) ⇒ Object
:nodoc:
423 424 425 426 427 428 429 430 431 |
# File 'lib/lafcadio/domain.rb', line 423 def self.field( fieldName ) #:nodoc: aDomainClass = self field = nil while aDomainClass < DomainObject && !field field = aDomainClass.class_field( fieldName ) aDomainClass = aDomainClass.superclass end field end |
.first ⇒ Object
Returns the first domain object it can find.
very_first_user = User.first
436 |
# File 'lib/lafcadio/domain.rb', line 436 def self.first; all.first; end |
.get(*args) ⇒ Object
This class method has a few uses, depending on how you use it.
-
Pass DomainObject.get a block in order to run a complex query:
adult_hwangs = User.get { |user| user.lastName.equals( 'Hwang' ) & user.birthday.lte( Date.today - ( 365 * 18 ) ) }
See query.rb for more information about how to form these queries.
-
Pass it a simple search term and a field name to retrieve every domain object matching the term. The field name will default to
pk_id
.hwangs = User.get( 'Hwang', :lastName ) user123 = User.get( 123 ).first
-
Pass it a { :group => :count } hash to retrieve a count result hash. This interface is fairly new and may be refined (that is, changed) in the future.
num_users = User.get( :group => :count ).first[:count]
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
# File 'lib/lafcadio/domain.rb', line 454 def self.get( *args ) if block_given? query = Query.infer( self ) { |dobj| yield( dobj ) } ObjectStore.get_object_store.query( query ) elsif args.size == 1 arg = args.first if arg.is_a? Fixnum ObjectStore.get_object_store.get( self, *args ) else qry = Query.new( self, :group_functions => [ :count ] ) ObjectStore.get_object_store.group_query qry end else search_term = args.shift field_name = ( args.shift or link_field( search_term.domain_class ).name ) qry = Query::Equals.new( field_name, search_term, self ) ObjectStore.get_object_store.query qry end end |
.get_class_fields ⇒ Object
Returns an Array of ObjectField instances for this domain class, parsing them from XML if necessary. You can override this to define a domain class’ fields, though it will probably just be simpler to use one-line class methods instead.
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
# File 'lib/lafcadio/domain.rb', line 480 def self.get_class_fields if self.methods( false ).include?( 'get_class_fields' ) [ subclass_record.pk_field ] elsif abstract_subclass?( self ) [] else xmlParser = try_load_xml_parser if xmlParser xmlParser.get_class_fields else error_msg = "Couldn't find either an XML class description file " + "or get_class_fields method for " + self.name raise MissingError, error_msg, caller end end end |
.is_child_domain_class? ⇒ Boolean
:nodoc:
497 498 499 |
# File 'lib/lafcadio/domain.rb', line 497 def self.is_child_domain_class? #:nodoc: superclass != DomainObject and !abstract_subclass?( superclass ) end |
.last ⇒ Object
Returns the last domain object.
last_msg = Message.last
504 |
# File 'lib/lafcadio/domain.rb', line 504 def self.last; all.last; end |
.link_field(linked_domain_class) ⇒ Object
:nodoc:
506 507 508 509 510 511 |
# File 'lib/lafcadio/domain.rb', line 506 def self.link_field( linked_domain_class ) # :nodoc: class_fields.find { |field| field.is_a? DomainObjectField and field.linked_type == linked_domain_class } end |
.maybe_call_default_mock(field, caller) ⇒ Object
:nodoc:
247 248 249 250 251 252 253 254 255 256 |
# File 'lib/lafcadio/test.rb', line 247 def self.maybe_call_default_mock( field, caller ) #:nodoc: linked_type = field.linked_type begin ObjectStore.get_object_store.get( linked_type, 1 ) rescue DomainObjectNotFoundError unless linked_type == caller linked_type.send( 'default_mock', self ) end end end |
.method_missing(methodId, *args) ⇒ Object
:nodoc:
513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/lafcadio/domain.rb', line 513 def self.method_missing( methodId, *args ) #:nodoc: dispatched = false method_name = methodId.id2name begin method_missing_try_create_field( method_name, *args ) dispatched = true rescue NameError begin method_missing_try_create_fields( method_name, *args ) dispatched = true rescue NameError; end end super unless dispatched end |
.method_missing_try_create_field(method_name, *args) ⇒ Object
:nodoc:
528 529 530 531 532 |
# File 'lib/lafcadio/domain.rb', line 528 def self.method_missing_try_create_field( method_name, *args ) # :nodoc: maybe_field_class_name = method_name.underscore_to_camel_case + 'Field' field_class = Lafcadio.const_get( maybe_field_class_name ) create_field( field_class, *args ) end |
.method_missing_try_create_fields(method_name, *args) ⇒ Object
:nodoc:
534 535 536 537 538 539 540 541 542 543 |
# File 'lib/lafcadio/domain.rb', line 534 def self.method_missing_try_create_fields( method_name, *args ) # :nodoc: singular = method_name.singular if singular maybe_field_class_name = singular.underscore_to_camel_case + 'Field' field_class = Lafcadio.const_get( maybe_field_class_name ) create_fields( field_class, *args ) else raise NameError end end |
.mock_value(field_sym, value) ⇒ Object
Sets the mock value for the given field. These mock values are used in DomainObject.default_mock and DomainObject.custom_mock
This class method is only visible if you include lafcadio/test.rb
.
class User < Lafcadio::DomainObject
strings :fname, :lname, :email
end
User.mock_value :fname, 'Bill'
User.mock_value :lname, 'Smith'
u1 = User.default_mock
u1.fname # => 'Bill'
u1.lname # => 'Smith'
u1.email # => 'test text'
u1.pk_id # => 1
274 275 276 |
# File 'lib/lafcadio/test.rb', line 274 def self.mock_value( field_sym, value ) @@default_arg_directives[self][field_sym.id2name] = value end |
.mock_values(hash) ⇒ Object
Sets the mock value for the fields in hash
. These mock values are used in DomainObject.default_mock and DomainObject.custom_mock
This class method is only visible if you include lafcadio/test.rb
.
class User < Lafcadio::DomainObject
strings :fname, :lname, :email
end
User.mock_values { :fname => 'Bill', :lname => 'Smith' }
u1 = User.default_mock
u1.fname # => 'Bill'
u1.lname # => 'Smith'
u1.email # => 'test text'
u1.pk_id # => 1
293 294 295 |
# File 'lib/lafcadio/test.rb', line 293 def self.mock_values( hash ) hash.each do |field_sym, value| mock_value( field_sym, value ); end end |
.only ⇒ Object
Returns the only committed instance of the domain class. Will raise an IndexError if there are 0, or more than 1, domain objects.
the_one_user = User.only
549 |
# File 'lib/lafcadio/domain.rb', line 549 def self.only; all.only; end |
.postgres_pk_id_seq ⇒ Object
551 552 553 |
# File 'lib/lafcadio/domain.rb', line 551 def self.postgres_pk_id_seq "#{ table_name }_#{ sql_primary_key_name }_seq" end |
.require_domain_file(typeString) ⇒ Object
:nodoc:
555 556 557 558 559 560 561 562 563 564 565 566 567 |
# File 'lib/lafcadio/domain.rb', line 555 def self.require_domain_file( typeString ) # :nodoc: typeString =~ /([^\:]*)$/ fileName = $1 domain_dirs.each { |domainDir| if Dir.entries(domainDir).index("#{fileName}.rb") require "#{ domainDir }#{ fileName }" end } if (domainFiles = LafcadioConfig.new['domainFiles']) domainFiles = domainFiles.split( ',' ) if domainFiles.is_a? String domainFiles.each { |domainFile| require domainFile } end end |
.self_and_concrete_superclasses ⇒ Object
:nodoc:
569 570 571 572 573 574 575 576 577 578 579 |
# File 'lib/lafcadio/domain.rb', line 569 def self.self_and_concrete_superclasses # :nodoc: classes = [ ] a_domain_class = self until( a_domain_class == DomainObject || abstract_subclass?( a_domain_class ) ) classes << a_domain_class a_domain_class = a_domain_class.superclass end classes end |
.singleton_method_added(symbol) ⇒ Object
:nodoc:
581 582 583 584 585 586 587 588 589 |
# File 'lib/lafcadio/domain.rb', line 581 def self.singleton_method_added( symbol ) # :nodoc: if symbol.id2name == 'sql_primary_key_name' && self < DomainObject begin field( 'pk_id' ).db_field_name = self.send( symbol ) rescue NameError subclass_record.sql_primary_key = self.send( symbol ) end end end |
.sql_primary_key_name(set_db_field_name = nil) ⇒ Object
If set_db_field_name
is nil, this will return the sql name of the primary key. If set_db_field_name
isn’t nil, it will set the sql name.
class User < Lafcadio::DomainObject
string 'firstNames'
end
User.sql_primary_key_name # => 'pk_id'
class User < Lafcadio::DomainObject
sql_primary_key_name 'some_other_id'
end
User.sql_primary_key_name # => 'some_other_id'
602 603 604 605 |
# File 'lib/lafcadio/domain.rb', line 602 def self.sql_primary_key_name( set_db_field_name = nil ) field( 'pk_id' ).db_field_name = set_db_field_name if set_db_field_name field( 'pk_id' ).db_field_name end |
.subclass_record ⇒ Object
:nodoc:
607 608 609 |
# File 'lib/lafcadio/domain.rb', line 607 def self.subclass_record # :nodoc: @@subclass_records.synchronize { @@subclass_records[self] } end |
.subclasses ⇒ Object
:nodoc:
611 612 613 |
# File 'lib/lafcadio/domain.rb', line 611 def self.subclasses #:nodoc: @@subclass_records.keys end |
.table_name(set_table_name = nil) ⇒ Object
If set_table_name
is nil, DomainObject.table_name will return the table name. Lafcadio assumes that a domain class corresponds to a table whose name is the pluralized, lower-case, underscored version of the class name. A User class is assumed to be stored in a “users” table, while a ProductCategory class is assumed to be stored in a “product_categories” table.
If set_table_name
is not nil, this will set the table name.
class User < Lafcadio::DomainObject
string 'firstNames'
end
User.table_name # => 'users'
class User < Lafcadio::DomainObject
table_name 'some_table'
end
User.table_name # => 'some_table'
632 633 634 635 636 637 638 639 640 641 642 643 644 645 |
# File 'lib/lafcadio/domain.rb', line 632 def self.table_name( set_table_name = nil ) if set_table_name @table_name = set_table_name elsif @table_name @table_name else xmlParser = try_load_xml_parser if (!xmlParser.nil? && table_name = xmlParser.table_name) table_name else self.basename.camel_case_to_underscore.plural end end end |
.try_load_xml_parser ⇒ Object
:nodoc:
647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'lib/lafcadio/domain.rb', line 647 def self.try_load_xml_parser # :nodoc: if ( dirName = LafcadioConfig.new['classDefinitionDir'] ) xmlFileName = self.basename + '.xml' xmlPath = File.join( dirName, xmlFileName ) begin xml = File.open( xmlPath ) do |f| f.gets( nil ); end ClassDefinitionXmlParser.new( self, xml ) rescue Errno::ENOENT # no xml file, so no @xmlParser end end end |
Instance Method Details
#clone ⇒ Object
Returns a clone, with all of the fields copied.
690 691 692 693 694 695 |
# File 'lib/lafcadio/domain.rb', line 690 def clone copy = super copy.field_values = @field_values.clone copy.fields_set = @fields_set.clone copy end |
#commit ⇒ Object
Commits this domain object to the database.
698 699 700 |
# File 'lib/lafcadio/domain.rb', line 698 def commit ObjectStore.get_object_store.commit self end |
#delete! ⇒ Object
Deletes a domain object, committing the delete to the database immediately.
713 714 715 716 |
# File 'lib/lafcadio/domain.rb', line 713 def delete! self.delete = true commit end |
#domain_class ⇒ Object
Returns the subclass of DomainObject that this instance represents. Because of the way that proxying works, clients should call this method instead of Object.class.
721 722 723 |
# File 'lib/lafcadio/domain.rb', line 721 def domain_class self.class.domain_class end |
#field_value(field) ⇒ Object
:nodoc:
725 726 727 728 729 730 |
# File 'lib/lafcadio/domain.rb', line 725 def field_value( field ) #:nodoc: unless @fields_set.include?( field ) set_field_value( field, @fieldHash[field.name] ) end @field_values[field.name] end |
#getter_field(methId) ⇒ Object
:nodoc:
732 733 734 |
# File 'lib/lafcadio/domain.rb', line 732 def getter_field( methId ) #:nodoc: self.class.field methId.id2name end |
#post_commit_trigger ⇒ Object
This template method is called after every commit. Subclasses can override it to ensure code is executed after a commit.
774 775 776 |
# File 'lib/lafcadio/domain.rb', line 774 def post_commit_trigger nil end |
#pre_commit_trigger ⇒ Object
This template method is called before every commit. Subclasses can override it to ensure code is executed before a commit.
754 755 756 |
# File 'lib/lafcadio/domain.rb', line 754 def pre_commit_trigger nil end |
#preprocess_field_hash(fieldHash) ⇒ Object
:nodoc:
758 759 760 761 762 763 764 765 766 767 768 769 770 |
# File 'lib/lafcadio/domain.rb', line 758 def preprocess_field_hash( fieldHash ) # :nodoc: if fieldHash.is_a? Hash fieldHash.keys.each { |key| if self.class.field( key.to_s ).nil? raise ArgumentError, "Invalid field name #{ key.to_s }" end } @fieldHash = {} fieldHash.each do |k, v| @fieldHash[k.to_s] = v; end else @fieldHash = fieldHash end end |
#reset_original_values_hash(f = @field_values) ⇒ Object
:nodoc:
778 779 780 |
# File 'lib/lafcadio/domain.rb', line 778 def reset_original_values_hash( f = @field_values ) #:nodoc: @original_values = ReadOnlyHash.new( f.clone ) end |
#set_field_value(field, value) ⇒ Object
:nodoc:
782 783 784 785 786 787 788 789 790 791 792 793 794 795 |
# File 'lib/lafcadio/domain.rb', line 782 def set_field_value( field, value ) #:nodoc: if ( field.is_a?( DomainObjectField ) and !value.is_a?( DomainObjectProxy ) and value ) value = DomainObjectProxy.new(value) end if ( LafcadioConfig.new()['checkFields'] == 'onAllStates' && !field.instance_of?( PrimaryKeyField ) ) field.verify( value, pk_id ) end @field_values[field.name] = value @fields_set << field end |
#setter_field(methId) ⇒ Object
:nodoc:
797 798 799 800 801 802 803 |
# File 'lib/lafcadio/domain.rb', line 797 def setter_field( methId ) #:nodoc: if methId.id2name =~ /(.*)=$/ self.class.field $1 else nil end end |
#update!(changes) ⇒ Object
Updates a domain object and commits the changes to the database immediately.
user99 = User[99]
user99.update!( :firstNames => 'Bill', :password => 'n3wp4ssw0rd' )
810 811 812 813 |
# File 'lib/lafcadio/domain.rb', line 810 def update!( changes ) changes.each do |sym, value| self.send( sym.to_s + '=', value ); end commit end |
#verify ⇒ Object
If you’re running against a MockObjectStore, this will verify each field and raise an error if there’s any invalid fields.
817 818 819 820 821 822 823 |
# File 'lib/lafcadio/domain.rb', line 817 def verify if ObjectStore.mock? self.class.get_class_fields.each { |field| field.verify( self.send( field.name ), self.pk_id ) } end end |