Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

madsem's avatar

Select Game With Screenshot Relationship But Only Where Screenshots Exist. Query Not Working

I'm trying to select Games with Screenshot relationship, but only where at least one Screenshot image exists. For some reason it also includes Games without existing screenshots and I am really unsure why that happens.

End-result expected: Get 3 games, with one screenshot in size "t_screenshot_huge" where hypes are greater than 1, order results by random so always get different results.

This is my query:

Game::with([
                'screenshots' => function ($query) {
                    $query->where('size_label', '=', 't_screenshot_huge');
                }
            ])->where('hypes', '>', 1)->orderByRaw('RAND()')->take(3)->get();

That's the resulting Collection (first Game, without screenshot images)

Collection {#342 ▼
  #items: array:3 [▼
    0 => Game {#353 ▼
      #guarded: array:1 [▶]
      #connection: "mysql2"
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:23 [▼
        "id" => 22
        "slug" => "backgammon-masters"
        "name" => "Backgammon Masters"
        "summary" => null
        "storyline" => null
        "hypes" => 7
        "popularity" => 0.0
        "rating" => 20.0
        "rating_count" => 0
        "aggregated_rating" => 0.0
        "aggregated_rating_count" => 0
        "total_rating" => 20.0
        "total_rating_count" => 0
        "first_release_date" => null
        "status" => "Released"
        "esrb" => "RP (Rating Pending)"
        "pegi" => "16"
        "website" => null
        "deleted_at" => null
        "created_at" => "2018-03-06 14:16:17"
        "updated_at" => "2018-03-06 14:16:17"
        "cover_image" => null
        "cover_image_original" => null
      ]
      #original: array:23 [▶]
      #changes: []
      #casts: []
      #dates: []
      #dateFormat: null
      #appends: []
      #dispatchesEvents: []
      #observables: []
      #relations: array:1 [▼
        "screenshots" => Collection {#354 ▼
          #items: []
        }
      ]
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #fillable: []
      #forceDeleting: false
    }
    1 => Game {#355 ▶}
    2 => Game {#362 ▶}
  ]
}
0 likes
5 replies
BezhanSalleh's avatar

change with to whereHas that way you will get what you want...

Game::whereHas( 'screenshots' => function ($query) {
                   $query->where('size_label', '=', 't_screenshot_huge');
             })
             ->where('hypes', '>', 1)
             ->orderByRaw('RAND()')
             ->take(3)
             ->get();
1 like
madsem's avatar

Thanks that fixed it @BezhanSalleh :)

but your version gives an error, whereHas() only accepts a string.

Game::whereHas('screenshots', function ($query) {
                $query->where('size_label', '=', 't_screenshot_huge');
            }
        )->where('hypes', '>', 1)->orderByRaw('RAND()')->take(3)->get();
madsem's avatar
madsem
OP
Best Answer
Level 4

sorry @BezhanSalleh I gotta steal the accepted answer away from you, because after all it did not work as required.

Your query selects all relationships with screenshots, but it did not select the size required...

To achieve this, one has to query like this:

Game::whereHas('screenshots')
                       ->with([
                           'screenshots' => function ($query) {
                               $query->where('size_label', '=', 't_screenshot_huge');
                           }
                       ])->where('hypes', '>', 1)
                         ->orderByRaw('RAND()')
                         ->take(3)
                         ->get();

Hope this helps someone in the future :)

BezhanSalleh's avatar

@madsem accepted or not doesn't matter, all that matter is that it helped you get what you were looking for and i'm glad that it did. cheers mate!

1 like

Please or to participate in this conversation.