1
votes

I'm using Symfony2 with PropelBundle, and lets say I have the following schema:

<table name="person">
  <column name="id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
  <column name="name" type="VARCHAR" size="100" required="true"/>
</table>
<table name="person_parent">
  <column name="person_id" type="INTEGER" primaryKey="true" required="true"/>
  <column name="parent_id" type="INTEGER" primaryKey="true" required="true"/>
</table>

Consider that a person can have many "Parents", just like a parent can have many child "Persons". Both of the columns in the "person_parent" table are foreign keys to the "person" table. Unlike for relationships like Book/Author where one can set isCrossRef="true" in the schema of table "book_author" to let Propel generate methods for directly getting/setting/adding book objects from an author class or viceversa, for Parent/Child relationships it is not possible to set isCrossRef="true" and thus not possible to get/set/add Parent Person objects directly from a "Person" Object. In other words it is not possible to do:

$person = new Person();
$person->setPersonParents($personCollection);

The method "setPersonParents()" to set all the parent "Person" objects of any given person is not available. However, for cross tables that do not reference to the same table like author_book, setting isCrossRef="true" allows for the following:

$author = new Author();
$author->setBooks($bookCollection);

With that in mind, it is also not possible to directly select a Person's "Parents" in a "New Person" Form...

For friend like relationships there is the EqualNestBehavior, which allows for:

$person = new Person();
$person->setFriends($personCollection);

However, that behavior does not seem applicable to Parent/Child relationships since it does not care about hierarchy (if one tries to get the "Parents" of any given "Person", one gets all the "Childs" of that "Person" in addition to its "Parents"...). This is the behavior one would expect for "friend like" relationships, where a Friend of a Person is also that Person's Friend.

Is there a way to use the EqualNestBehavior for the Parent/Child case? or is there any other Propel behavior or method to handle this kind of relationships?

1
Please, attach examples of code and schemaVitalii Zurian
What about using inheritance?William Durand
@thecatontheflat : I revised the problem statement to make it clear...RayOnAir
@WilliamDURAND : inheritance does not seem applicable since a Person who is a "Parent" can also be a child of another Person, thus I cannot create a "Child" class and "Parent" class since they both could refer to the same row...RayOnAir
You're right, I see your use case now.William Durand

1 Answers

1
votes

I am not sure about EqualNestBehavior but you could set up your workflow as following.

In your schema define FKs to Person table:

<table name="person">
    <column name="id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
    <column name="name" type="VARCHAR" size="100" required="true"/>
</table>
<table name="person_parent">
    <column name="person_id" type="INTEGER" primaryKey="true" required="true"/>
    <column name="parent_id" type="INTEGER" primaryKey="true" required="true"/>
    <foreign-key foreignTable="person" name="p1" onDelete="CASCADE" onUpdate="CASCADE">
        <reference local="person_id" foreign="id"/>
    </foreign-key>
    <foreign-key foreignTable="person" name="p2" onDelete="CASCADE" onUpdate="CASCADE">
        <reference local="parent_id" foreign="id"/>
    </foreign-key>
</table>

After that, when you generate models - you'll get such methods as:

$person = new Person();
$person->getPersonParentsRelatedByParentId();
$person->setPersonParentsRelatedByParentId($personCollection);

$person->getPersonParentsRelatedByPersonId();
$person->setPersonParentsRelatedByPersonId($personCollection);

Setters accept PropelCollection as argument.

You just have to think about this situation not like "get parents" or "get children", but as about related elements.