@aboutsam I think this a good candidate for a repository. You could tuck away the friend request query like this:
class FriendRequestRepository
{
public function forUser(User $user)
{
return FriendRequest::query()->where(function ($query) use ($user) {
$query->where('user_1_id', '=', $user->getKey());
$query->orWhere('user_2_id', '=', $user->getKey());
})->with('user_1', 'user_2')->get();
}
}
This will fetch FriendRequest models where either user_1_id or user_2_id is the given user’s ID.
However, you still need some logic to determine who the other user is. So you could map over the collection and return the other user:
class FriendRepository implements FriendRepositoryContract
{
protected $friendRequests;
public function __construct(FriendRequestRepository $friendRequests)
{
$this->friendRequests = $friendRequests;
}
public function forUser(User $user)
{
$friendRequests = $this->friendRequests->forUser($user);
return $friendRequests->map(function ($request) use ($user) {
if ($user->getKey() == $request->user_1_id) {
return $request->user_2;
} else {
return $request->user_1;
}
});
}
}
Now when calling app(FriendRepository::class)->forUser($user), you’ll get a collection of User models representing the friends of the given user.
You might want to “decorate” the repository with a caching version, too:
class CachingFriendRepository implements FriendRepositoryContract
{
protected $friends;
public function __construct(FriendRepository $friends)
{
$this->friends = $friends;
}
public function forUser(User $user)
{
$key = 'friends:user:'.$user->getKey(); // i.e.friends:user:123
return Cache::remember($key, $minutes = 30, function () {
return $this->friends->forUser($user);
});
}
}
But you’ll have to remember to clear the user’s cached friends if a request is saved or deleted:
FriendRequest::saved(function ($request) {
Cache::deleteMultiple([
'friends:user:'.$request->user_1_id,
'friends:user:'.$request->user_2_id,
]);
});
FriendRequest::deleted(function ($request) {
Cache::deleteMultiple([
'friends:user:'.$request->user_1_id,
'friends:user:'.$request->user_2_id,
]);
});
I think that’s enough. I’m getting carried away now! Ha-ha.