Skip to content

Commit

Permalink
Added orderByFollowersCount*() methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
overtrue committed Nov 4, 2021
1 parent 5fb2b71 commit 50c8ce1
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,20 @@ $user->attachFollowStatus($users);
```


### Order by followers count

You can query users order by followers count with following methods:

- `orderByFollowersCountDesc()`
- `orderByFollowersCountAsc()`
- `orderByFollowersCount(string $direction = 'desc')`

example:

```php
$users = User::orderByFollowersCountDesc()->get();
$mostPopularUser = User::orderByFollowersCountDesc()->first();
```

### N+1 issue

Expand Down
15 changes: 15 additions & 0 deletions src/Followable.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,21 @@ public function areFollowingEachOther($user): bool
return $this->isFollowing($user) && $this->isFollowedBy($user);
}

public function scopeOrderByFollowersCount($query, string $direction = 'desc')
{
return $query->withCount('followers')->orderBy('followers_count', $direction);
}

public function scopeOrderByFollowersCountDesc($query)
{
return $this->scopeOrderByFollowersCount($query, 'desc');
}

public function scopeOrderByFollowersCountAsc($query)
{
return $this->scopeOrderByFollowersCount($query, 'asc');
}

public function followers(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
{
/* @var \Illuminate\Database\Eloquent\Model $this */
Expand Down
50 changes: 48 additions & 2 deletions tests/FeatureTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,53 @@ function () use ($user1, $users) {


// with custom resolver
$posts = \collect(['author' => $user2], ['author' => $user3], ['author' => $user4]);
$user1->attachFollowStatus($posts, fn ($post) => $post['author']);
$users = \collect(['creator' => $user2], ['creator' => $user3], ['creator' => $user4]);
$user1->attachFollowStatus($users, fn ($post) => $post['creator']);
}

public function test_order_by_followers()
{
/* @var \Tests\User $user1 */
/* @var \Tests\User $user2 */
/* @var \Tests\User $user3 */
/* @var \Tests\User $user4 */
/* @var \Tests\User $user5 */
$user1 = User::create(['name' => 'user1']);
$user2 = User::create(['name' => 'user2']);
$user3 = User::create(['name' => 'user3']);
$user4 = User::create(['name' => 'user4']);
$user5 = User::create(['name' => 'user5']);

// user2: 2 followers
$user1->follow($user2);
$user3->follow($user2);

// user3: 0 followers
// user4: 1 followers
$user1->follow($user4);

// user1: 3 followers
$user2->follow($user1);
$user3->follow($user1);
$user4->follow($user1);

$usersOrderByFollowersCount = User::orderByFollowersCountDesc()->get();
// same as:
// $usersOrderByFollowersCount = User::withCount('followers')->orderByDesc('followers_count')->get();

$this->assertSame($user1->name, $usersOrderByFollowersCount[0]->name);
$this->assertEquals(3, $usersOrderByFollowersCount[0]->followers_count);
$this->assertSame($user2->name, $usersOrderByFollowersCount[1]->name);
$this->assertEquals(2, $usersOrderByFollowersCount[1]->followers_count);
$this->assertSame($user4->name, $usersOrderByFollowersCount[2]->name);
$this->assertEquals(1, $usersOrderByFollowersCount[2]->followers_count);
$this->assertSame($user3->name, $usersOrderByFollowersCount[3]->name);
$this->assertEquals(0, $usersOrderByFollowersCount[3]->followers_count);

$mostPopularUser = User::orderByFollowersCountDesc()->first();
// same as:
// $mostPopularUser = Post::withCount('followers')->orderByDesc('followers_count')->first();
$this->assertSame($user1->name, $mostPopularUser->name);
$this->assertEquals(3, $mostPopularUser->followers_count);
}
}

0 comments on commit 50c8ce1

Please sign in to comment.