如何在 yii2 restful api 中将两个 table 中的关系数据显示为 json 格式

how to display relation data into json format from two table in yii2 restful api

我在将来自两个 table 的数据显示为 JSON 格式并在 yii2 restful api 上工作时遇到问题。

这是我的结构数据库:

TABLE `volunteer`(
`volunteer_id` int(11) NOT NULL auto_increment,
`state_id` int(11) null 

TABLE `state`(
`state_id` int(11) NOT NULL auto_increment,
`state` varchar(225) null

volunteerController.php

public $modelClass = 'app\models\Volunteer';
public function behaviors()
{
    return ArrayHelper::merge(parent::behaviors(),[
        'verbs' => [
            'class' => VerbFilter::className(),
            'actions' => [
                'delete' => ['post'],
            ],
        ],
    ]);
}

config/web.php

'rules' => [
        ['class' => 'yii\rest\UrlRule', 'controller' => ['volunteer','state','post']],
],
'request' => [
        // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
        'cookieValidationKey' => 'QMoK0GQoN7_VViTXxPdTISiOrITBI4Gy',
                    'parsers' => [
                    'application/json' => 'yii\web\JsonParser',
                    ],

    ],

这是 JSON 格式的结果:

[
  {
    "volunteer_id": 1,
    "country_id": 1,
    "state_id": 12,
  }
]

所以那个结果不是我想要的。我想要的是 state_id 应该 return state 来自 table state 的数据,这意味着 state : New York 。不是 return state_id。如何解决这个问题呢 ?

这可以通过覆盖 fields() 来完成:

public function fields()
{
    return [
        'volunteer_id',
        'country_id',
        'state' => function ($model) {
            return $model->state->name; // Return related model property, correct according to your structure
        },
    ];
}

此外,您可以使用 with().

prepareDataProvider() 方法中预先加载此关系

官方文档:

public function fields(){
    return [
        'volunteer_id',
        'country_id',
        'state' => function ($model) {
            return $model->setOtherAttr($model->state_id); 
        },
        'other_attr1',
        'other_attr2',
    ];
}
public function setOtherAttr($state_id){
    $state = State::find()->where(['state_id'=>$state_id])->one();
    $this->other_attr1 = $state->other_attr1;
    $this->other_attr2 = $state->other_attr2;
    return $state->state;
}

试试下面的代码:

public function setOtherAttr($state_id){
  if (($model = State::find()->where(['state_id'=>$state_id])->all()) !== null) {
    return $model;
  } else {
   return '';
  }
}