Domain class inheritance

Inheritance can be achieved in Lafcadio by using separate tables, one for each level in a class hierarchy. For each record in the child table, there will also be one in the parent table as well. Retrievals will draw from both tables, and commits will affect both tables.

For example, let's imagine a web site with users, and administrators. Administrators are also users. Let's say the schemas look something like this:

create table users (
  pk_id       int not null auto_increment,
  primary key (pk_id),
  first_name  varchar(64),
  last_name   varchar(64),
  email       varchar(64) not null,
  password    varchar(64) not null,
  birthday    date
);

create table administrators (
  pk_id       int not null auto_increment,
  primary key (pk_id),
  granted_by  int,
  last_login  datetime
);

The matching Ruby code looks like this:

class User < Lafcadio::DomainObject
  string 'first_name'
  string 'last_name'
  string 'email'
  string 'password'
  date   'birthday'
end

class Administrator < User
  domain_object User, 'granted_by'
  date_time     'last_login'
end

Users and administrators can now be instantiated and retrieved naturally. Lafcadio handles the work of matching primary keys, and stitching together the results of multiple SQL statements.

user1 = User.new(
  'first_name' => 'John',
  'last_name' => 'Doe',
  'email' => 'john.doe@email.com'
).commit

admin2 = Administrator.new(
	'first_name' => 'Jane',
  'last_name' => 'Doe',
  'email' => 'jane.doe@email.com',
  'last_login' => Time.now
).commit

user1_pk_id = user1.pk_id     # most likely 1
admin2_pk_id = admin2.pk_id   # most likely 2
user1_prime = User[user1_pk_id]
admin2_prime = Administrator[admin2_pk_id]

One important caveat: Lafcadio does not correctly protect you from retrieving, as a parent instance, an instance that might more correctly be a child. For example, the following code will work in Lafcadio:

user2_prime = User[admin2_pk_id]

This code retrieves an instance of User, using a pk_id that could just as well be an Administrator, and it will contain only the methods and data of a User instance. Lafcadio will not detect that this is happening, so your program logic should not assume that just because it was possible to retrieve it as a User that it is not an Administrator.