Quick search:


How to make a persistent class polymorphic

First read what is polymorphic persistency. Then choose one of the three ways to map polymorphic classes to relational tables. If you have chosen the third way, this page will not help you. Example 12 demonstrates how to do it for the second way.

For simplicity we assume you have a superclass and one or more subclasses that together are to be polymorpic and persistent. If you have chosen to map all classes to a single table, all you have to do is:
  1. The usual for a peristent class, see how to make instances of a class persistent.
  2. Define a persistent field property in the superclass for the class name and a column in the table with the same name. The column needs to be of type varchar and must be long enough to hold the longest class name of all the classes in the polymorphism. If you do not want the class name to be visible in the user interface, you can let the name of the property end with Id, or you can override the getUiFieldPaths method, see how to override which propeties show up in the user interface.
  3. From the constructor of the superclass, initialize the field to
    $this->getClass(). This method returns the original class name in correct case, as long as you use the includeClass() function to include the class file (example).
  4. In the initPropertyDescriptors method of the superclass, get the ClassDescriptor, and set the name of the persistent field property you defined in step 2 through its setPolymorphismPropName method. This must be done before the super::initPropertyDescriptors call (example)

If you want to map a subclasses to a different table, all you have to do is define a different tablename on the subclass, as usual by overriding the getTableName method. The table of the class should contain a column for the id (primary, but not autoincrement), and a column for each persistent fieldProperty that is added by the class. Inherited or redifined properties will be mapped to the table of the superclass. You should not override the propertyDescriptors from the superclass in such a way that the table of the superclass can not store the values from the instances of the subclass.

You can also make a mix of classes mapped to their own table and classes that are not. Anyway, you should not define new persistent fieldproperties on subclasses that are not mapped to their own table.

Make sure all subclasses either have no constructor, or call the proper constructor of their superclass. If the constructor that initializes the field of the polymorphism property is not called, there will be no classname stored in the database. The framework will then instantiate the object from the superclass instead of from the proper subclass.