在控制器中,我有以下代码:
public function actionView($id){ $query = new Query; $query->select('*') ->from('table_1 t1') ->innerJoin('table_2 t2', 't2.t1_id = t1.id') ->innerJoin('table_3 t3', 't2.t3_id = t3.id') ->innerJoin('table_4 t4', 't3.t4_id = t4.id') ->andWhere('t1.id = ' . $id); $rows = $query->all(); return $this->render('view', [ 'model' => $this->findModel($id), 'rows' => $rows, ]);}
在视图view.php中显示来自table_2-4的数据,这些数据与table_1相干:
foreach($rows as $row) { echo $row['t2_field_1']; echo $row['t2_field_2']; ...}
它能够工作,然而我不确定这是否是最正确的Yii2办法.
我试图在模型TableOne中定义关系:
public function getTableTwoRecords(){ return $this->hasMany(TableTwo::className(), ['t1_id' => 'id']);}public function getTableThreeRecords(){ return $this->hasMany(TableThree::className(), ['id' => 't3_id']) ->via('tableTwoRecords');}public function getTableFourRecords(){ return $this->hasMany(TableFour::className(), ['id' => 't4_id']) ->via('tableThreeRecords');}
而后在控制器TableOneController中退出记录:
$records = TableOne::find() ->innerJoinWith(['tableTwoRecords']) ->innerJoinWith(['tableThreeRecords']) ->innerJoinWith(['tableFourRecords']) ->all();
然而它不起作用.如果我仅退出前三个表,那么它将起作用.如果增加第四张表,则会收到以下谬误音讯:"获取未知属性:frontend \ models \ TableOne :: t3_id"
如果我以这种形式更改函数getTableFourRecords():
public function getTableFourRecords(){ return $this->hasOne(TableThree::className(), ['t4_id' => 'id']);}
而后我收到此谬误音讯:"SQLSTATE [42S22]:找不到列:1054'on子句'中的未知列'table_4.t4_id'正在执行的SQL是:SELECT table_1 .* FROM table_1 INNER JOIN table_2 ON table_1 . id = table_2 . t1_id INNER JOIN table_3 ON table_2 . t3_id = table_3 . id INNER JOIN table_4 ON table_1 . id = table_4 . t4_id "
解决办法:
Model TableOne:
public function getTableTwoRecords() { return $this->hasMany(TableTwo::className(), ['t1_id' => 'id']); }
Model TableTwo:
public function getTableThreeRecord() { return $this->hasOne(TableThree::className(), ['id' => 't3_id']); }
Model TableThree:
public function getTableFourRecord(){ return $this->hasOne(TableFour::className(), ['id' => 't4_id']);}
Controller TableOneController:
public function actionView($id){ return $this->render('view', [ 'model' => $this->findModel($id), ]);}
The view table-one/view.php:
foreach ($model->tableTwoRecords as $record) { echo ' Table 2 >> '; echo ' ID: ' . $record->id; echo ' T1 ID: ' . $record->t1_id; echo ' T3 ID: ' . $record->t3_id; echo ' Table 3 >> '; echo ' ID: ' . $record->tableThreeRecord->id; echo ' T4 ID: ' . $record->tableThreeRecord->t4_id; echo ' Table 4 >> '; echo ' ID: ' . $record->tableThreeRecord->tableFourRecord->id; echo ' <br>';}
也能够应用基于GridView的解决方案.
模型TableTwo:
foreach ($model->tableTwoRecords as $record) { echo ' Table 2 >> '; echo ' ID: ' . $record->id; echo ' T1 ID: ' . $record->t1_id; echo ' T3 ID: ' . $record->t3_id; echo ' Table 3 >> '; echo ' ID: ' . $record->tableThreeRecord->id; echo ' T4 ID: ' . $record->tableThreeRecord->t4_id; echo ' Table 4 >> '; echo ' ID: ' . $record->tableThreeRecord->tableFourRecord->id; echo ' <br>';}
应用yii为TableTwo模型生成的TableOneController中的actionView函数已被编辑:
use app\models\TableTwo;use app\models\TableTwoSearch;...public function actionView($id){ $searchModel = new TableTwoSearch([ 't1_id' => $id, // the data have to be filtered by the id of the displayed record ]); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); return $this->render('view', [ 'model' => $this->findModel($id), 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, ]);}
以及views/table-one/view.php的代码如下:
echo GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ 'id', 't1_id', 'tableOneRecord.id', 't3_id', 'tableThreeRecord.id', 'tableThreeRecord.t4_id', 'tableFourRecord.id', ],]);