bugfix> php > 投稿

次のような2つのテーブルがあります。

stocks

id | name      | market_cap
1  | Microsoft | 5000
2  | Tesla     | 2000

このテーブルは、というタイトルのテーブルと1対多の関係にあります。 stock_ratings

id | stock_id | measure | value
12 | 1        | revenue | 30
13 | 1        | dividend| 5
14 | 2        | revenue | 10
15 | 2        | dividend| 0

ここで、ユーザーがすべての株を取得したいとします。 market_cap > 3000 、最初の20件の結果をスキップして、次の20件を取得します。これは機能します。

$query = Stock::where('market_cap', '>', 3000);
$stocks = $query->skip(20)->take(20)->get();

ただし、ユーザーはstock_ratingsについてもクエリできる必要があります。したがって、上記の条件に加えて、次のようなすべての株を検索したいとします。 value > 20 のために revenue 測定します。

これを試しましたが、機能しません。この追加条件がない場合と同じ株式リストが返されます。

$query = Stock::where('market_cap', '>', 3000);
$query = $query->with(['ratings' => function ($q) {
    $q->where('stock_ratings.measure', 'revenue');
    $q->where('stock_ratings.value', '>', 0);
}]);
$stocks = $query->skip(20)->take(20)->get();

これにより、すべての株式が返されます market_cap > 3000 拘らず value そして measure の中に stock_ratings テーブル。マイナスの株を返します valuestock_ratings どこ measure = revenue また、stock_ratingsに関連する行がまったくない行も返します。

これを解決するにはどうすればよいですか?

回答 1 件
  • で制約を適用する場合 with これは、ネストされた関連レコードを熱心にロードする必要があり、熱心にロードしてはならない制約が適用されることを意味します。

    ただし、あなたの場合、関連する格付けに含まれる値に基づいて、株式をフィルタリングまたは制約を適用する必要があります。

    だからこれを試してみてください

    $query = Stock::where('market_cap', '>', 3000);
    $query = $query->whereHas('ratings', function ($q) {
        $q->where('measure', 'revenue');
        $q->where('value', '>', 0);
    })-with('ratings');
    $stocks = $query->skip(20)->take(20)->get();
    
    

    Laravelのドキュメントで詳細を読む:https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

あなたの答え