Yii2:在多个表之间定义关系的正确方法

Posted VE视频引擎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Yii2:在多个表之间定义关系的正确方法相关的知识,希望对你有一定的参考价值。

在控制器中,我有以下代码:

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\',
    ],
]);

以上是关于Yii2:在多个表之间定义关系的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

识别和非识别关系之间有什么区别?

雄辩:定义模型和迁移中的关系之间的区别

使用两个字段在两个表之间创建关系

Yii2使用关系删除查询

线性表

Android:在视图/活动/片段之间滑动切换