Один из самых приятных в программировании (лично для меня) моментов — это когда тяжелый и запутанный код становится прозрачным. В одном из текущих проектов я отказался от паттерна Active Record в пользу паттерна Data Mapper.
Вот как выглядел один из методов контроллера:
public function actionIncludedUnits($id) { $unitsTable = \app\models\Unit::tableName(); $unitsBundlesTable = \app\models\UnitsBundle::tableName(); $unitsGroupsTable = \app\models\unitsGroups\UnitsGroup::tableName(); $tangiblesTable = \app\models\tangibles\Tangible::tableName(); $query = "SELECT u.id unitId, ug.id unitsGroupId, ug.division_slug slug, ug.group_num l, u.group_num r, t.name tangibleName FROM {$unitsBundlesTable} ub LEFT JOIN {$unitsTable} u ON u.bundle_of_units_id = ub.id LEFT JOIN {$unitsGroupsTable} ug ON u.units_group_id = ug.id LEFT JOIN {$tangiblesTable} t ON u.tangible_id = t.id WHERE ub.complex_unit_id = :id"; $raw = Yii::$app->db->createCommand($query) ->bindValue(':id', $id) ->queryAll(); $res = []; foreach ($raw as $item) { $res[$item['unitId']] = [ 'unitsGroupNumber' => sprintf('%02d/%02d', $item['l'], $item['r']), 'tangibleName' => $item['tangibleName'], 'unitUrl' => \yii\helpers\Url::to([ 'units/view', 'slug' => $item['slug'], 'group' => $item['unitsGroupId'], 'id' => $item['unitId'] ]), ]; } return (\yii\helpers\Json::encode($res)); }
Вот как он выглядит сейчас:
public function actionIncludedUnits($id) { $units = (new mappers\UnitMapper)->search([ 'Unit' => [ 'complexUnitId' => $id, ], ]); $res = []; foreach ($units->getModels() as $unit) $res[$unit->id] = [ 'unitsGroupNumber' => $unit->spoNumberOutput(), 'tangibleName' => $unit->tangible->name, 'categoryName' => $unit->tangible->category->name, 'unitUrl' => \yii\helpers\Url::to([ 'units/view', 'slug' => $unit->unitsGroup->divisionSlug, 'group' => $unit->unitsGroup->id, 'id' => $unit->id, ]), ]; return \yii\helpers\Json::encode($res); }
Здесь, конечно, вся работа лежит под капотом, и все же понять, что происходит теперь гораздо проще, а сам код стал элегантнее.