web-dev-qa-db-ja.com

laravel 4-Eloquent ORMを制限(取得およびスキップ)する方法は?

TL; DR

take()およびskip()を使用するようなEloquent ORMクエリを制限して、結果のmysqlクエリも制限され、データセット全体を返す必要がないようにできますか?

もしそうなら、どのように変更しますか:

_$test = User::find(1)->games->toArray();
_

_limit 3 offset 2_を含めるには?


テーブル:

_users       games           userGames
-- id       -- id           -- user_id
-- name     -- name         -- game_id
            -- Steam_id
_

モデル:

_class User extends Eloquent {
    public function games() {
        return $this->belongsToMany('Game', 'userGames', 'user_id', 'game_id');
    }
}

class Game extends Eloquent {
    public function users() {
        return $this->belongsToMany('User', 'userGames', 'user_id', 'game_id');
    }
}
_

クエリビルダーの制限

通常のLaravel Query Builderを使用すると、ID 1のgamesに属するすべてのuserを取得でき、結果を制限できます。 take()およびskip()

_$test = DB::table('games')
    ->join('userGames', 'userGames.game_id', '=', 'games.id')
    ->where('userGames.user_id', '=', '1')->take(3)->skip(2)->get();
_

_illuminate.query_イベントをリッスンすることにより、これによって生成されたクエリが次のようになることがわかります。

_select * from `games`
inner join `userGames`
on `userGames`.`game_id` = `games`.`id`
where `userGames`.`user_id` = ?
limit 3 offset 2
_

Eloquent ORMの制限

Eloquentで同じクエリを再作成しようとすると:

_$test = User::find(1)->games->take(2)->toArray();
_

takeを使用できますが、skipを追加するとエラーが発生します。また、結果のクエリには実際には制限が含まれていません。

_select `games`.*, `userGames`.`user_id` as `pivot_user_id`,
`userGames`.`game_id` as `pivot_game_id` from `games`
inner join `userGames`
on `games`.`id` = `userGames`.`game_id`
where `userGames`.`user_id` = ?
_

そのため、結果全体が最初にクエリされているように見えますが、これは大きなデータセットを扱う場合には理想的ではありません。


質問:

Eloquent ORMクエリを制限して、MYSQLクエリレベルで結果を制限することは可能ですか(_limit 3 offset 2_と同等)?

17
Johannes
_User::find(1)->games()->take(3)->skip(2)->get();
_

これであなたのコレクションが得られると思います。 :)

_->games_はコレクションを提供し、->games()はクエリビルダーインスタンスを提供します。

Laravelをお楽しみください!

50
daylerees