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

nikocraft's avatar

return posts where author = $username

I have a posts model that has this relationship to the User:

public function author()
{
    return $this->belongsTo(User::class, 'user_id');
}

i am building a search function and I have this code

public function index(Request $request)
{
    $search = $request->search;
    $filter = $request->filter;

    $append = array();

    $posts = Post::with('author')->with('categories')->latest();

    if($search){
        switch ($filter) {
            case 'username':
                $posts->author->where('username', 'LIKE', '%'. $search . '%');
            break;
        }
        $append += array('search' => $search);
        $append += array('filter' => $filter);
    }

    $posts = $posts->paginate(3);
    $posts->appends($append);

    return view('core.blog.posts.index', compact('posts'));
}

I get

Undefined property: Illuminate\Database\Eloquent\Builder::$author

How do I add where that looks for author based on his username? I must be able to add this condition in an if case

0 likes
5 replies
Snapey's avatar
Snapey
Best Answer
Level 122

create a scope on Post model like;

    public function scopeAuthor($query,$author)
    {
        if(!Empty($author)){

            return $query->whereHas('author', function ($query) use ($author) {
                        $query  ->where('username', 'like', "%{$author}%");
        }
        return $query;
    }

Then you can use this to filter your posts

change the controller like;

    $search = $request->search;
    $filter = $request->filter;

    $append = array();

    if($search){
        switch ($filter) {
            case 'username':
                  $posts = Post::author($search)->with('author')->with('categories')->latest();
            break;
        }
        $append += array('search' => $search);
        $append += array('filter' => $filter);
    }

    $posts = $posts->paginate(3);
    $posts->appends($append);

    return view('core.blog.posts.index', compact('posts'));


So, it passes the search term to the scope

the scope checks if a search term has been passed (so it works if no search specified) and then uses WhereHas to limit posts to only those having an author named like the search term

1 like
nikocraft's avatar

thanks @Snapey actually I found a solution, I needed to use whereHas

            case 'username':
                $posts->whereHas('author', function($query) use($search) {
                    $query->where('username', $search);
                });
            break;

Also I forgot to mention, any solution must not modify this line

    $posts = Post::with('author')->with('categories')->latest();

Since I need to eager load author and categories even if user has not searched anything, so doing this:

    $posts = Post::author($search)->with('author')->with('categories')->latest();

breaks my search flow

nikocraft's avatar

well actually you also suggested whereHas which is what was needed here :)

Snapey's avatar

and i also kept your line, eager loading the authors and categories... i just added scope to it

just read replies more carefully. These things take time to write and it's insulting when you spend less time reading it and dismissing.

1 like
nikocraft's avatar

sorry, yes you kept the line but moved it inside the if statement which does not work for me. your suggestion to use whereHas is correct though and the scope you introduced in my case would look like

            case 'username':
                $posts->author();
            break;

anyways thanks for answering, I meant not to insult :)

I've upvoted and selected your answer :)

Please or to participate in this conversation.