Best way to get related data from models in yii and return json

Hi just a question

im working on the rest of the application for the project using sproutcore on the front panel.

My question is really what is the most efficient way to capture data from a model with other related models when you need to return json. Yesterday I read that it is recommended to work with the DAO layer when working with arrays, so for my example this is what I have.

I have a list of customers, each HAS_MANY customer and each HAS_MANY brand. Do not get a beautifully formed array of customers back with their brands that I have

$clients = Yii::app()->db->createCommand('select client.* from client where client.status = 1')->queryAll();

        foreach($clients as $ckey => $client)
        {
            $clients[$ckey] = $client;
            $brand_ids = Yii::app()->db->createCommand('select brand.id as brand_id, brand.client_id as b_client_id from brand where brand.client_id ='.$client['id'])->queryAll();

            foreach($brand_ids as $bkey => $brand_id)
            {
                $clients[$ckey]['brands'][] = $brand_id['brand_id'];
            }

    }

This returns what I want, but is it the most effective way to achieve what they are after?

+5
3

class Client extends CActiveRecord
{    
    //...
    /**
     * @return array relational rules.
     */
    public function relations()
    {
            // NOTE: you may need to adjust the relation name and the related
            // class name for the relations automatically generated below.
            return array(
                    'brands' => array(self::HAS_MANY, 'Brand', 'client_id'),
            );
    }
    //...
    public function defaultScope() {
        return array('select'=>'my, columns, to, select, from, client'); //or just comment this to select all "*"
    }

}

class Brand extends CActiveRecord
{
    //...
    /**
     * @return array relational rules.
     */
    public function relations()
    {
            // NOTE: you may need to adjust the relation name and the related
            // class name for the relations automatically generated below.
            return array(
                    'client' => array(self::BELONGS_TO, 'Client', 'client_id'),
            );
    }
    //...
    //...
    public function defaultScope() {
        return array('select'=>'my, columns, to, select, from, brand'); //or just comment this to select all "*"
    }

}

/

$clients = Client::model()->with('brands')->findAllByAttributes(array('status'=>1));

$clientsArr = array();
if($clients) {
    foreach($clients as $client) {
        $clientsArr[$client->id]['name'] = $client->name; //assign only some columns not entire $client object.
        $clientsArr[$client->id]['brands'] = array();

        if($client->brands) {
            foreach($client->brands as $brand) {
                $clientsArr[$client->id]['brands'][] = $brand->id;
            }
        }

    }
}

print_r($clientsArr);
/*
Array (
    [1] => Array (
        name => Client_A,
        brands => Array (
            0 => Brand_A,
            1 => Brand_B,
            2 => Brand_C
        )
    )
    ...
)

*/

? , - ( ), sql GROUP_CONCAT (MySQL) , . 1,2,3,4,5,20,45,102.

+3

CActiveRecord, with() , SQL-, brand.

$rows = Yii::app()->db
    ->createCommand(
        'SELECT c.*, b.id as brand_id 
        FROM client c INNER JOIN brand b 
        WHERE c.status = 1 AND b.client_id = c.id')
    ->queryAll();
$clients = array();
foreach ($rows as row) {
    if (!isset($clients[$row['id']])) {
        $clients[$row['id']] = $row;
        $clients[$row['id']]['brands'] = array();
    }
    $clients[$row['id']]['brands'][] = $row['brand_id'];
}

, , N ( N - ). projects .

+1

, , , , .

Controller (protected/Components/Controller.php) :

protected function renderJsonDeep($o) {
    header('Content-type: application/json');
        // if it an array, call getAttributesDeep for each record
    if (is_array($o)) {
        $data = array();
        foreach ($o as $record) {
            array_push($data, $this->getAttributesDeep($record));
        }
        echo CJSON::encode($data);
    } else {
            // otherwise just do it on the passed-in object
        echo CJSON::encode( $this->getAttributesDeep($o) );
    }

        // this just prevents any other Yii code from being output
    foreach (Yii::app()->log->routes as $route) {
        if($route instanceof CWebLogRoute) {
            $route->enabled = false; // disable any weblogroutes
        }
    }
    Yii::app()->end();
}

protected function getAttributesDeep($o) {
        // get the attributes and relations
        $data = $o->attributes;
    $relations = $o->relations();
    foreach (array_keys($relations) as $r) {
            // for each relation, if it has the data and it isn't nul/
        if ($o->hasRelated($r) && $o->getRelated($r) != null) {
                    // add this to the attributes structure, recursively calling
                    // this function to get any of the child relations
            $data[$r] = $this->getAttributesDeep($o->getRelated($r));
        }
    }
    return $data;
}

renderJsonDeep JSON, , , , "" DbCriteria.

- , JSON, getAttributesDeep .

, -.

+1

All Articles