我目前正在使用AngularJs制作Yii2 RESTful系统。
在我的数据库中,我有几个列,我希望能够从我系统中的某个点进行特定呼叫时返回。
我遇到的问题是如何从系统另一部分的restful调用中返回少量字段,例如(id,title和stub),以便忽略表中的其他字段。
理想情况下,我希望它与模型规则如何与yii中的场景一起工作。
答案 0 :(得分:1)
我认为有两种方法:
// returns all fields as declared in fields()
http://localhost/users
// only returns field id and email, provided they are declared in fields()
http://localhost/users?fields=id,email
// returns all fields in fields() and field profile if it is in extraFields()
http://localhost/users?expand=profile
// only returns field id, email and profile, provided they are in fields() and extraFields()
http://localhost/users?fields=id,email&expand=profile
// explicitly list every field, best used when you want to make sure the changes
// in your DB table or model attributes do not cause your field changes (to keep API backward compatibility).
public function fields()
{
return [
// field name is the same as the attribute name
'id',
// field name is "email", the corresponding attribute name is "email_address"
'email' => 'email_address',
// field name is "name", its value is defined by a PHP callback
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// filter out some fields, best used when you want to inherit the parent implementation
// and blacklist some sensitive fields.
public function fields()
{
$fields = parent::fields();
// remove fields that contain sensitive information
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
更多细节,请参阅https://github.com/yiisoft/yii2/blob/master/docs/guide/rest-resources.md
答案 1 :(得分:0)
您可以在模型中使用 scenario 方法,但为了使其正常工作,您必须扩展一点 toArray 方法:
public function scenarios()
{
return array_merge(parent::scenarios(), [
'simple_info' => [
'email',
'name',
],
'login' => [
'id',
'email',
'name',
'auth_token',
],
]);
}
public function toArray(array $fields = array(), array $expand = array(), $recursive = true)
{
$scenarios = $this->scenarios();
$scenario = $this->getScenario();
if (!empty($scenarios[$scenario])) {
$data = parent::toArray($fields, $expand, $recursive);
return array_intersect_key($data, array_flip($scenarios[$scenario]));
}
return parent::toArray($fields, $expand, $recursive);
}
在此之后你可能会做这样的事情:
$model = new LoginForm();
if ($model->load(Yii::$app->request->post(), '') && $model->login()) {
$user = $model->getUser();
// Lets change scenario to login in order to get `auth_token` for authorization
$user->setScenario('login');
$user->generateAuthKey();
$user->save(FALSE);
return $user;
} else {
return $model;
}
答案 2 :(得分:0)
作为旁注(扩展@Ganiks的答案),如果您手动返回模型列表,则需要将它们作为DataProvider(而不仅仅是模型数组)返回给{{ 1}}参数有效。
例如,如果您这样做......
fields
...然后class UserController extends yii\rest\Controller
{
public function actionIndex()
{
return User::find()->all(); // Not what you want
}
// ...
}
参数将没有所需的效果。但是,如果你改为这样做......
fields
...然后返回的字段将只是您在class UserController extends yii\rest\Controller
{
public function actionIndex()
{
return new ActiveDataProvider([
'query' => User::find(),
'pagination' => false,
]);
}
// ...
}
参数中指定的字段。