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.