1

i have two models User and Friend , User has a foreign key in Friend (user_id) since it's a HasMany relation, so i added a function that returns the friendships of the current user

    public static function searchFriend(){
        return Friend::whereUserId(Auth::id())
            ->orWhere('friend_id',Auth::id())->get();
    }

now i want to search into the current user's friends by firstname so i have to query his friendships and access to the related users through the foreign key user_id or friend_id and query by firstname , how can i apply a query on the returned results by the searchFriend() function

  $friends = Friend::searchFriend();
CoderTn
  • 985
  • 2
  • 22
  • 49
  • How does the relation between User and Friend work? Is it an n-m relation and Friend is used as pivot table? where is the firstname saved? My first advice would be to remove the get() call from teh searchFriend and only return the QueryBuilder, so you can add something like a firstname search to the query when you need it – Gesit Sep 03 '21 at 11:04
  • @Geist5000 it's one to many relation so the User has many friends – CoderTn Sep 03 '21 at 11:08

3 Answers3

1

Did you add the relationship?

public function friends() {
    return $this->hasMany(Friend:class);
}

Then you can simply do $user->friends()->where(‘first_name’, ‘John’)->get();

Ozan Kurt
  • 3,731
  • 4
  • 18
  • 32
  • thank you for the answer @Ozan, i have been using the exact same relation you added in your answer, the problem with that is it returns only the friendships where the current user's id is in the user_id column, however i want to return the friendships where the current user's id is in the user_id or friend_id columns that's why in my function i am using the where and orWhere – CoderTn Sep 03 '21 at 11:13
  • So you actually have a 2 way relationship? `User A` can be the friend of `User A` AND `User B` can be a friend of `User A`. – Ozan Kurt Sep 03 '21 at 12:13
  • For all the friend stuff like this I recommend you use a package. https://github.com/multicaret/laravel-acquaintances This one is extremely good. – Ozan Kurt Sep 03 '21 at 12:14
0

try this,

Friend model:-

public function user(){
        return $this->belongsTo('App\User','user_id');
    }

use Illuminate\Support\Facades\Auth;

  $first_name = $request->first_name ?? "";
  $friends =  Friend::whereHas('user',function($q){
    $q->where('id',Auth::id());
  })->where("first_name","=","%{$first_name}%")->get();
Yudiz Solutions
  • 4,216
  • 2
  • 7
  • 21
0

A solution with minimal changes to your current codebase would be to remove the get() call from the searchFriend() function and move the where statements into a Closure (more infos here):

public static function searchFriend(){
    return Friend::where(function ($query) {
        $query->where('user_id',Auth::id())
            ->orWhere('friend_id',Auth::id());
    }
}

The Closure is needed because of the "and" priorisation in the resulting query. Read about it here.

Use it like this: $friends = Friend::searchFriend()->where('firstname','John')->get();

This solution should work, but I would advice you to change the function to something like this:

User.php

public function friends(){
    return Friend::where(function ($query) {
        $query->where('user_id',$this->id())
            ->orWhere('friend_id',$this->id());
    }
}

And do your firstname search like this: $friends = $request->user()->friends()->where('firstname','John')->get()

Gesit
  • 329
  • 2
  • 13