Relying on BELONGS_TO relations after querying ‘with-through’ turned out to be a bad idea. These properties aren’t cached during the query, so every access means additional query for every row in the relations table which is unacceptable.
My solution was to add ‘index’ property to the first relation of the first table, set to the field which is a foreign key of the second table, so that rows queried from the relations table are indexed by IDs of the second table (as rows from the relations table and second table are one-to-one in this query). This way, after the request, I can iterate through rows of the second table and get corresponding rows from the relations table.
[ First.php ]
public function relations()
{
return array(
'rels' => array(
self::HAS_MANY, 'Rel.php', 'firstId',
'index' => 'secondId'),
'seconds' => array(
self::HAS_MANY, 'Second.php', 'secondId',
'through' => 'rels'),
);
}
public function getWithSeconds($id)
{
$first = $this->findByPk($id, array('with' => array('rels', 'seconds')));
foreach ($first->seconds as $second)
$second->propertyFromRel = $first->rels[$second->id]->property;
return $first;
}