I had a situation where whenever I returned a model of mine, I always wanted to know something about it. For example, pretend we have a Book model. We also have a User model. Finally, we have a BooksRead model, where we map user_ids to book_ids, to determine whether or not a book was read.

Wouldn’t it be nice to know, if a user is viewing a book, if they’ve already read that book (or haven’t)?

Let’s take a look at our book model.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class Book extends Model
{

    protected $appends = ['completedByCurrentUser'];

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

}

Alright, pretty basic. We just have an Eloquent relationship setup with the User model. Now, let’s go ahead and add a custom attribute to this model. We’ll call it ‘currentUserHasReadBook’. It’s pretty lengthy, but it definitely lets you know what it is!

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class Book extends Model
{

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


    public function getCurrentUserHasReadBook()
    {
        return count(BooksRead::where([['book_id', $this->id], ['user_id', Auth::user()->id]])->get()->toArray()) > 0;
    }

}

So with this, we’re just returning true/false based on the count of BooksRead that match with the user ID. If we wanted to return the book instead, we could just do:

    public function getCurrentUserHasReadBook()
    {
        return BooksRead::where([['book_id', $this->id], ['user_id', Auth::user()->id]])->get();
    }

Now, this won’t always return whenever you request this model. To do that, we need to add an appends.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class Book extends Model
{

    protected $appends = ['currentUserHasReadBook'];

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


    public function getCurrentUserHasReadBook()
    {
        return count(BooksRead::where([['book_id', $this->id], ['user_id', Auth::user()->id]])->get()->toArray()) > 0;
    }

}

And there you have it! Now whenever you request a book, you’ll always know whether or not the currently logged in user has read it or not!

Leave a Reply

Your email address will not be published. Required fields are marked *