如何在 Yii 中设置和返回从请求中获得的虚拟属性值


How to set and return virtual attribute value got from request in Yii

我在ActiveRecord类中有一个虚拟公共属性。当我在类中收到JSON RawBodyActiveController我正在尝试将解析的 JSON 分配给$model->attributes。请求 JSON 如下所示:

{
  "name": "test",
  "address": "a place on earth",
  "_id": 1
} 

现在在上面的 JSON _id 是我在类中声明为public $_id; ActiveRecord键,我也为此属性使用了 setter getter,如下所示:

public function setId ($value) 
{
    $this->_id = $value;
}
public function getId ($value)
{
    return $this->_id;
}

主动控制器方法:

public function actionPush() 
{
    $data = $this->getRequestData();
    $model = new User();
    $model->attributes = $data;
    if($model->save())
        return ['status' => 200, 'message' => 'Record added successfully', 'record' => $model];
    return ['status' => 400, 'message' => 'Records not updated', 'errors' => $errors];
}
public function getRequestData()
{
    $body = 'Yii::$app->request->getRawBody();
    $parser = new JsonParser();
    return $parser->parse($body, 'application/json');
}

现在我想要这样的回应:

{
    "status": 200,
    "message": "Record added successfully",
    "record": {
            "id": 10,
            "name": "test",
            "_id": 1
        }
}

但是像这样:

{
    "status": 200,
    "message": "Record added successfully",
    "record": {
            "id": 10,
            "name": "test"
        }
}

我如何获得结果?

情况 1:您要用 _id 替换id

如果您的模型已经有一个名为 id 的属性,那么我不确定覆盖现有数据库属性是否是一种好的做法。我建议重写 yii''base''Model::fields((,因为它是在内置的 Yii RESTful API 中完成的(参见文档(。这样,你将保留模型的原始实例,以便在应用内在需要时使用,并将$model->fields()绑定到用户终结点或输出。

我认为您在这里甚至不需要虚拟属性。 如果您打算手动设置或更新模型的主键,则 id_id 之间的映射器属性可能就足够了。 这可以在 setter 方法中完成。将此添加到您的模型中:

// remember to add '_id' to safe attributes (model::rules)
public function set_id ($value)
{
    $this->id = $value;
}
public function fields()
{
    $fields = parent::fields();
    unset($fields['id']);
    $fields['_id'] = $this->id;
    // or $fields['_id'] = $this->getPrimaryKey();
    return $fields;
}

然后强制actionPush()返回$model->fields()而不是$model

public function actionPush() 
{
    $data = $this->getRequestData();
    $model = new User();
    $model->attributes = $data;
    if($model->save())
        return [
            'status' => 200, 
            'message' => 'Record added successfully',
            'record' => $model->fields();
        ];
    return ['status' => 400, 'message' => 'Records not updated', 'errors' => $errors];
}

情况2:你想同时保持id_id

添加第二种情况,因为我想我可能误解了你的问题。 如果要保留和维护属性id_id

"record": {
   "id": 10,
   "_id": 1
   "name": "test",
}

然后这将解决问题:

private $_id;
public function get_id ()
{
    return $this->_id;
}
public function set_id ($value)
{
    $this->_id = $value;
}
public function fields()
{
    $fields = parent::fields();
    $fields['_id'] = '_id';
    return $fields;
}

注意:如果 ''yii''web''Response 设置为 'yii'web'Response::FORMAT_JSON,Yii 将使用 fields 来检索属性(可以在配置文件或 ContentNegotiator 中设置(。否则,如果您使用不同的格式化程序,则可以手动调用$model->fields()而不是$model来输出数据。