0 フォロワー

コレクションのフィルタリング

リソースコレクションは、2.0.13以降、yii\data\DataFilterコンポーネントを使用してフィルタリングできます。これにより、リクエストを介して渡されたフィルタ条件を検証および構築し、拡張版yii\data\ActiveDataFilterの助けを借りて、yii\db\QueryInterface::where()に適した形式で使用できます。

フィルタリングのためのデータプロバイダの設定

コレクションセクションで述べたように、ソートおよびページネーションされたリソースリストを出力するためにデータプロバイダを使用できます。また、それを使用してリストをフィルタリングすることもできます。

$filter = new ActiveDataFilter([
    'searchModel' => 'app\models\PostSearch',
]);

$filterCondition = null;
// You may load filters from any source. For example,
// if you prefer JSON in request body,
// use Yii::$app->request->getBodyParams() below:
if ($filter->load(Yii::$app->request->get())) { 
    $filterCondition = $filter->build();
    if ($filterCondition === false) {
        // Serializer would get errors out of it
        return $filter;
    }
}

$query = Post::find();
if ($filterCondition !== null) {
    $query->andWhere($filterCondition);
}

return new ActiveDataProvider([
    'query' => $query,
]);

PostSearchモデルは、フィルタリングに許可されるプロパティと値を定義する目的を果たします。

use yii\base\Model;

class PostSearch extends Model 
{
    public $id;
    public $title;
    
    public function rules()
    {
        return [
            ['id', 'integer'],
            ['title', 'string', 'min' => 2, 'max' => 200],            
        ];
    }
}

検索ルールのためのスタンドアロンモデルを準備する代わりに、特別なビジネスロジックが不要な場合はyii\base\DynamicModelを使用できます。

$filter = new ActiveDataFilter([
    'searchModel' => (new DynamicModel(['id', 'title']))
        ->addRule(['id'], 'integer')
        ->addRule(['title'], 'string', ['min' => 2, 'max' => 200]),
]);

エンドユーザーに許可されるフィルタ条件を制御するために、searchModelの定義が必要です。

フィルタリングのリクエスト

エンドユーザーは通常、許可された1つ以上のメソッド(APIドキュメントで明示的に述べる必要があります)を使用して、リクエストでオプションのフィルタ条件を提供することが期待されます。たとえば、フィルタリングがJSONを使用したPOSTメソッドで処理される場合、次のようになります。

{
    "filter": {
        "id": {"in": [2, 5, 9]},
        "title": {"like": "cheese"}
    }
}

上記の条件は

  • idは2、5、または9のいずれかである必要があります AND
  • titleにはcheeseという単語が含まれている必要があります。

GETクエリの一部として送信された同じ条件は次のとおりです。

?filter[id][in][]=2&filter[id][in][]=5&filter[id][in][]=9&filter[title][like]=cheese

デフォルトのfilterキーワードを変更するには、yii\data\DataFilter::$filterAttributeNameを設定します。

フィルタ制御キーワード

許可されるフィルタ制御キーワードのデフォルトリストは次のとおりです。

フィルタ制御次のように変換されます
and AND
or OR
not NOT
lt <
gt >
lte <=
gte >=
eq =
neq !=
in IN
nin NOT IN
like LIKE

オプションyii\data\DataFilter::$filterControlsを拡張することでそのリストを拡張できます。たとえば、同じフィルタビルドキーに対して複数のキーワードを提供し、次のように複数のエイリアスを作成できます。

[
    'eq' => '=',
    '=' => '=',
    '==' => '=',
    '===' => '=',
    // ...
]

指定されていないキーワードは、フィルター制御として認識されず、属性名として扱われることに注意してください。制御キーワードと属性名の間の競合を避ける必要があります(たとえば、制御キーワードにlikeがあり、likeという名前の属性がある場合、そのような属性の条件を指定することは不可能になります)。

注意:フィルター制御を指定する際には、APIが使用する実際のデータ交換形式を考慮してください。指定された各制御キーワードがその形式に対して有効であることを確認してください。たとえば、XMLではタグ名は文字で始まる必要があり、>=$gtなどの制御はXMLスキーマを壊します。

注意:新しいフィルター制御ワードを追加する場合は、yii\data\DataFilter::$conditionValidators および/または yii\data\DataFilter::$operatorTypes を更新する必要があるかどうかを確認してください。これは、演算子の複雑さやその動作方法に基づいて、期待されるクエリ結果を得るために必要です。

Null 値の処理

JSONステートメント内ではnullを簡単に使用できますが、GETクエリを使用して送信する場合、リテラルのnullと文字列の"null"を混同せずに送信することはできません。2.0.40以降では、yii\data\DataFilter::$nullValueオプションを使用して、リテラルのnullの代わりに使われる単語を設定できます(デフォルトでは"NULL"です)。

属性のエイリアス

属性に別の名前でエイリアスを付けたい場合や、結合されたDBテーブルをフィルター処理したい場合は、yii\data\DataFilter::$attributeMap を使用してエイリアスのマップを設定できます。

[
    'carPart' => 'car_part', // carPart will be used to filter car_part property
    'authorName' => '{{author}}.[[name]]', // authorName will be used to filter name property of joined author table
]

ActiveController のフィルター設定

yii\rest\ActiveController には、yii\rest\IndexAction::$dataFilter プロパティを介してフィルターを使用するように簡単に構成できる便利な一般的なRESTアクションのセットが付属しています。その1つの方法として、yii\rest\ActiveController::actions()を使用する方法があります。

public function actions()
{
    $actions = parent::actions();
    
    $actions['index']['dataFilter'] = [
        'class' => \yii\data\ActiveDataFilter::class,
        'attributeMap' => [
            'clockIn' => 'clock_in',
        ],
        'searchModel' => (new DynamicModel(['id', 'clockIn']))->addRule(['id', 'clockIn'], 'integer', ['min' => 1]),
    ];
    
    return $actions;
}

これで、コレクション(indexアクションを介してアクセス)をidおよびclockInプロパティでフィルタリングできます。

タイプミスを見つけましたか?または、このページの改善が必要だと思いますか?
githubで編集する !