title: Refactor a section of query-building to the Eloquent model and make it chainable with other Builders
body: <p>I want to refactor the <code>withCount</code> part from the following code to reuse it and make the controller shorter.</p>
  <pre class="lang-php prettyprint-override"><code>class GroupController extends Controller
  {
      public function show(int $group = 1)
      {
          return Group::where('id', '&gt;', 0)  // to simulate starting the query with some builder
              -&gt;withCount([
                  &quot;requests&quot;,
                  'requests AS requests_count_pending' =&gt; function ($query) {
                      $query-&gt;where('state', 'pending');
                  },
                  'requests AS requests_count_accepted' =&gt; function ($query) {
                      $query-&gt;where('state', 'accepted');
                  },
                  'requests AS requests_count_refused' =&gt; function ($query) {
                      $query-&gt;where('state', 'refused');
                  }
              ])
              -&gt;find($group);
      }
  }
  </code></pre>
  <p><strong>I want to build the query with the following syntax:</strong></p>
  <pre class="lang-php prettyprint-override"><code>$group = Group::where('id', '&gt;', 0)
      ::withCountRequests()
      -&gt;find($group);
  </code></pre>
  <hr />
  <hr />
  <h2>What I tried (Patch)</h2>
  <pre><code>public static function withRequestsCount()
  {
      return self::withCount([
          &quot;requests&quot;,
          'requests AS requests_count_pending' =&gt; function ($query) {
              $query-&gt;where('state', 'pending');
          },
          'requests AS requests_count_accepted' =&gt; function ($query) {
              $query-&gt;where('state', 'accepted');
          },
          'requests AS requests_count_refused' =&gt; function ($query) {
              $query-&gt;where('state', 'refused');
          }
      ]);
  }
  </code></pre>
  <pre><code>public function show(int $group = 1)
  {
      return Group::withRequestsCount()
          -&gt;where('id', '&gt;', 0)
          -&gt;find($group);
  }
  </code></pre>
  <p>The solution works only when I call the static method first. But I want to chain it fluently like any other <code>Builder</code></p>
  <hr />
  <hr />
  <h2>Reproducing</h2>
  <pre><code>php .\artisan make:model -mcrf Group
  php .\artisan make:model -mcrf Request
  </code></pre>
  <h3>Migrations</h3>
  <pre class="lang-php prettyprint-override"><code>public function up(): void
  {
      Schema::create('groups', function (Blueprint $table) {
          $table-&gt;id();
          $table-&gt;timestamps();
      });
  }
  </code></pre>
  <pre class="lang-php prettyprint-override"><code>public function up(): void
  {
      Schema::create('requests', function (Blueprint $table) {
          $table-&gt;id();
          $table-&gt;timestamps();
          $table-&gt;set('state', ['pending', 'accepted', 'refused']);
          $table-&gt;foreignId('group_id');
      });
  }
  </code></pre>
  <h3>Models</h3>
  <pre><code>class Group extends Model
  {
      use HasFactory;
  
      public function requests()
      {
          return $this-&gt;hasMany(Request::class);
      }
  }
  </code></pre>
  <h3>Factory and seeder</h3>
  <pre class="lang-php prettyprint-override"><code>class RequestFactory extends Factory
  {
      public function definition(): array
      {
          return [
              'group_id' =&gt; 1,
              'state' =&gt; $this-&gt;faker-&gt;randomElement(['pending', 'accepted', 'refused']),
          ];
      }
  }
  </code></pre>
  <pre class="lang-php prettyprint-override"><code>class DatabaseSeeder extends Seeder
  {
      public function run()
      {
          DB::table('groups')-&gt;insertOrIgnore(['id' =&gt; 1]);
  
          Request::factory(50)-&gt;create();
      }
  }
  </code></pre>
  <h2>Route</h2>
  <pre class="lang-php prettyprint-override"><code>Route::get('the_group', [GroupController::class, 'show']);
  </code></pre>