Search code examples
phpormpropel

Propel fail in creating an instance of a concrete class with inheritance?


I can't find a way to use findOrCreate() with single inheritance and abstract parent class in Propel. This little example gives me a fatal error:

Fatal error: Cannot instantiate abstract class ComicBook propel\query\ModelCriteria.php on line 1181

The query that throws this fatal error is fairly simple:

$thebook = ComicBookQuery::create()->filterById(1)->findOneOrCreate();

A little piece of database schema:

<table name="book" abstract="true" phpName="AbstractBook">
    <column name="id" type="INTEGER" required="true"
       primaryKey="true" autoIncrement="true"/>
    <column name="type" type="VARCHAR" size="255" required="true"
       inheritance="single">
        <inheritance key="Abstract" class="AbstractBook"/>
        <inheritance key="ComicBook" class="ComicBook" extends="AbstractBook"/>
    </column>
</table>

Is there any way to get inheritance working with abstract parent class?


Solution

  • The main issue with the single table inheritance is that you always fake things. You get this error because the real model is AbstractBook, nothing else...

    With abstract=false, you'll be able to instanciate an AbstractBook (which won't be abstract at all…), and then it will be transformed into a ComicBook.

    By setting abstract=true, you cannot instantiate an AbstractBook. Overriding to the rescue!

    I didn't dig a lot in the code but, if you want to create ComicBook with findOneOrCreate(), you'll have to override the following method: getModelName() in your ComicBookQuery class:

    <?php
    
    class ComicBookQuery extends BaseComicBookQuery {
    
        public function getModelName()
        {
            return 'ComicBook';                                                                                                                              
        }
    
    } // ComicBookQuery
    

    It's a best practice to override methods to fit your needs ;)