Call to a member function addEagerConstraints() on null, custom key in model Laravel

189 views Asked by At

I'm refactoring a personal Laravel project and I got blocked in the way of improving it.

The function worked this way:

1. Get a collection from the model Thread

2. A foreach loop checks if a User voted that very thread, adding a custom key->value

3. Return the collection

What I had working up until now, was this:

ThreadController:

$threads = Thread::orderBy('created_at', 'desc')
->with('communities')
->with('author')
->withCount('replies')
->withCount('upvotes')
->withCount('downvotes')
->paginate(4);

foreach ($threads as $thread) {
            if (Auth::user()) {
                if (Vote::where('user_id', '=', Auth::user()->id)->where('thread_id', '=', $thread->id)->where('vote_type', '=', 1)->exists()) {
                    $thread->user_has_voted = 'true';
                    $thread->user_vote_type = 1;
                } elseif (Vote::where('user_id', '=', Auth::user()->id)->where('thread_id', '=', $thread->id)->where('vote_type', '=', 0)->exists()) {
                    $thread->user_has_voted = 'true';
                    $thread->user_vote_type = 0;
                } else {
                    $thread->user_has_voted = 'false';
                }
            }
        }

return $threads;

What I would like to do is something like this:

Thread Model:

public function userVoteThread() {
    if (Vote::where('user_id', '=', Auth::user()->id)
    ->where('thread_id', '=', $this->id)
    ->where('vote_type', '=', 1)
    ->exists()) {
        return $this->user_vote_type = 1;
    } elseif (Vote::where('user_id', '=', Auth::user()->id)
    ->where('thread_id', '=', $this->id)
    ->where('vote_type', '=', 0)
    ->exists()) {
        return $this->user_vote_type = 0;
    }
}

ThreadController:

$threads = Thread::orderBy('created_at', 'desc')
->with('communities')
->with('author')
->with('userVoteThread') <----- ADDING NEW MODEL FUNCTION
->withCount('replies')
->withCount('upvotes')
->withCount('downvotes')
->paginate(4);

After all, the closest I got was this error Call to a member function addEagerConstraints() on null, and I'm stuck trying to improve the code.

Is there a way to make that Thread model function work and use it through the collection?

Thank you very much!

PS: I hope I made myself understood, otherwise, ask me about it. Thank you :D

1

There are 1 answers

1
mrhn On

Firstly add relationship to the Thread model.

class Thread {
    public function votes() {
        return $this->hasMany(Thread::class);
    }
}

Add your Eloquent Accessor to the Thread.

class Thread {
    public function getUserVoteTypeAttribute() {
        $this->votes
            ->where('user_id', Auth::user()->id ?? -1)
            ->first()->user_vote_type ?? null;
    }

    public function getUserHasVotedAttribute() {
        return $this->user_vote_type !== null;
    }
}

Now you can access these attributes on your model.

$thread = Thread::with('votes')->find(1);

$thread->user_vote_type;
$thread->user_has_voted;