Extending a Model

Hi all,

First of all, thanks for all the hard work. Love Phalcon and we're just starting to use it on a big project. There is one problem I can't easily work around.

How would one make a child-parent relationship between Phalcon MVC models? This is a DB schema I have in mind:

```sql explain show; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | length | int(11) | NO | | NULL | | | title | varchar(100) | NO | | NULL | | +---------+--------------+------+-----+---------+-------+

explain showepisode; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | showid | int(11) | NO | PRI | NULL | | | season | int(11) | NO | | NULL | | | episode | int(11) | NO | | NULL | | +---------+--------------+------+-----+---------+-------+```

Each element in show_episode is also present in show table, however there are show records which are only present in show.

The idea is to have two Phalcon Model classes:

```php class Show extends Phalcon\Mvc\Model { public $id; public $length; public $title; }

class ShowEpisode extends Show { public $season; public $episode; }``` How would I need to configure those models to be able to retrieve and save episode records like this:

```php// retrieve $episode = ShowEpisode::findFirst(array("id"=>333)); echo $episode->season; echo $episode->title;

// save $episode->title = "New Title"; $episode->season = 3; $episode->save();```

Thanks for the help!

Best, Matej



33.4k

You don't need to extend. Leave them as 2 separate models:

 class Show extends Phalcon\Mvc\Model
{
  public $id;
  public $length;
  public $title;

  public function initialize()
  {
        $this->hasMany('id', 'ShowEpisode', 'show_id', array(
            'alias' => 'episodes'
        ));
  }
}

class ShowEpisode extends Phalcon\Mvc\Model
{
  public $season;
  public $episode;

  public function initialize()
  {
        $this->belongsTo('show_id', 'Show', 'id', array(
            'alias' => 'show'
        ));
  }
}

Hi Chalin,

thank you for your answer. It seems that you misunderstood the question, though. The point of this (example) DB schema is that each episode is also a show.

So, when you create a new episode, you should be able to do it like that: ```php $episode = new ShowEpisode(); $episode->title = "Episode title"; $episode->length = 30; $episode->season = 1; $episode->episode = 3; $episode->save(); ```

This should result in two records, one in "show" and one in "show_episode" table. It is a 0..1 to 1 relationship.

Until I figure out a better way, I solved it by placing this code into the child model. Obviously it is bad in terms of optimisation and it doesn't solve fetching, just the saving part. ```php

class ShowEpisode extends Show { /* ... */

protected function _getShow()
{
    return $this->getRelated("show");
}

public function initialize()
{
$this->hasOne("id", "Show", "id", array("alias"=> "show", "foreignKey"=>true));
    parent::initialize();
}

public function save($data=null, $whiteList=null)
{
    $reflect = new \ReflectionClass($this);
    $properties = $reflect->getProperties();

    // create parent object
    $show = $this->_getShow();

    if (!$show) {
        $show = new Show();
    }

    // assign child variables to parent
    foreach ($properties as $prop) {
        if ($prop->class == "Show") {
            $show->{$prop->name} = $this->{$prop->name};
        }
    }

    $show->save();
    $this->id = $show->getId();

    parent::save($data, $whiteList);
}

} ```

Are there any other ways to achieve the same?