Table of Contents

Model Relationship Recipes

These are examples of Solar_Sql_Model relationships. They serve as extractable “recipes” to be combined in different model schemes.

See also:

Basic ''HasMany'' / ''BelongsTo''

<?php
class Vendor_Model_Layout extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'layout';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
        );
 
        // All pages using this layout.
        $this->_hasMany('pages', array(
            'foreign_class' => 'Vendor_Model_Page',
            'foreign_key'   => 'layout_id',
        ));
    }
}
 
class Vendor_Model_Page extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'page';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'layout_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
        );
 
        // The layout used by this page.
        $this->_belongsTo('layout', array(
            'foreign_class' => 'Vendor_Model_Layout',
            'foreign_key'   => 'layout_id',
        ));
    }
}

Basic ''HasOne'' / ''BelongsTo''

<?php
class Vendor_Model_Auth extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'auth';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
        );
 
        // The user profile.
        $this->_hasOne('profile', array(
            'foreign_class' => 'Vendor_Model_Profile',
            'foreign_key'   => 'user_id',
        ));
    }
}
 
class Vendor_Model_Profile extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'profile';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'user_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
        );
 
        // The related user.
        $this->_belongsTo('user', array(
            'foreign_class' => 'Vendor_Model_Auth',
            'foreign_key'   => 'user_id',
        ));
    }
}

Basic Many To Many

<?php
class Vendor_Model_Layout extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'layout';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
        );
 
        // Map to sites.
        $this->_hasMany('layout2site', array(
            'foreign_class' => 'Vendor_Model_Layout2Site',
            'foreign_key'   => 'layout_id',
        ));
 
        // Sites where this layout is used.
        $this->_hasMany('sites', array(
            'foreign_class' => 'Vendor_Model_Site',
            'through'       => 'layout2site',
            'through_key'   => 'site_id',
        ));
    }
}
 
class Vendor_Model_Site extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'site';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
        );
 
        // Map to layouts.
        $this->_hasMany('layout2site', array(
            'foreign_class' => 'Vendor_Model_Layout2Site',
            'foreign_key'   => 'site_id',
        ));
 
        // Layouts used by this site.
        $this->_hasMany('layouts', array(
            'foreign_class' => 'Vendor_Model_Layout',
            'through'       => 'layout2site',
            'through_key'   => 'layout_id',
        ));
    }
}
 
class Vendor_Model_Layout2Site extends Solar_Model
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'layout2site';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'site_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
            'layout_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
        );
 
        $this->_belongsTo('site', array(
            'foreign_class' => 'Vendor_Model_Site',
            'native_key'    => 'site_id',
        ));
 
        $this->_belongsTo('layout', array(
            'foreign_class' => 'Vendor_Model_Layout',
            'native_key'    => 'layout_id',
        ));
    }
}

''HasMany'' and ''BelongsTo'' using only one model

This is a scheme used when the table has a parent_id field mapping to a record stored in the same table. Each record has many children records and also can have a parent record, all in the same table. If parent_id is 0, there's no parent record.

<?php
class Vendor_Model_Layout extends Solar_Model 
{
    /**
     *
     * Model setup.
     *
     * @return void
     *
     */
    protected function _setup()
    {
        $this->_table_name = 'layout';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'parent_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
        );
 
        // All children layouts.
        $this->_hasMany('layouts', array(
            'foreign_class' => 'Vendor_Model_Layout',
            'foreign_key'   => 'parent_id',
        ));
 
        // The parent layout.
        $this->_belongsTo('layout', array(
            'foreign_class' => 'Vendor_Model_Layout',
            'foreign_key'   => 'parent_id',
        ));
    }
}

''Many-to-Many'' (''Has-Many-Through'')

To setup a many-to-many relationship, we use a strategy called “has-many-through”: set an intermediate model – Vendor_Model_Article2Category – as a mapping model to Articles and Categories. This way, an Article can have multiple categories, while a Category can have multiple articles. Two hasMany relationships are needed in each Vendor_Model_Arcticle and Vendor_Model_Category: one for the mapping, and another for the related records.

<?php
class Vendor_Model_Article extends Solar_Sql_Model
{
    protected function _setup()
    {
        $this->_table_name = 'article';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'body' => 'clob',
        );
 
        $this->_hasMany('article2category', array(
            'foreign_class' => 'Vendor_Model_Article2Category',
            'foreign_col'   => 'article_id',
        ));
 
        $this->_hasMany('categories', array(
            'foreign_class'       => 'Vendor_Model_Category',
            'foreign_col'         => 'id',
            'through'             => 'article2category',
            'through_foreign_col' => 'category_id',
        ));
    }
}
 
class Vendor_Model_Category extends Solar_Sql_Model
{
    protected function _setup()
    {
        $this->_table_name = 'category';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'name' => array(
                'type'    => 'varchar',
                'size'    => '255',
                'require' => true,
            ),
        );
 
        $this->_hasMany('article2category', array(
            'foreign_class' => 'Vendor_Model_Article2Category',
            'foreign_col'   => 'category_id',
        ));
 
        $this->_hasMany('articles', array(
            'foreign_class'       => 'Vendor_Model_Article',
            'foreign_col'         => 'id',
            'through'             => 'article2category',
            'through_foreign_col' => 'article_id',
 
            'order'               => 'title ASC',
            'paging'              => 30,
        ));
    }
}
 
class Vendor_Model_Article2Category extends Solar_Sql_Model
{
    protected function _setup()
    {
        $this->_table_name = 'article2category';
 
        $this->_table_cols = array(
            'id' => array(
                'type'    => 'int',
                'primary' => true,
                'autoinc' => true,
            ),
            'created' => 'timestamp',
            'updated' => 'timestamp',
            'article_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
            'category_id' => array(
                'type'    => 'int',
                'require' => true,
            ),
        );
 
        $this->_belongsTo('article', array(
            'foreign_class' => 'Vendor_Model_Article',
            'native_col'    => 'article_id',
            'foreign_col'   => 'id',
        ));
 
        $this->_belongsTo('category', array(
            'foreign_class' => 'Vendor_Model_Category',
            'native_col'    => 'category_id',
            'foreign_col'   => 'id',
        ));
    }
}
?>