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

theUnforgiven's avatar

Undefined Property/Non-object on Relationship of 2 tables

Hi All,

I have a authors & books table With two models like so:

class Authors extends \Eloquent {

 protected $guarded = ['id'];

    public $table = 'authors';

    public $timestamps = false;

    public function book()
    {
        return $this->hasMany('Books', "author", "last_name");
    }

}
class Books extends \Eloquent {

 protected $guarded = ['id'];

    public $timestamps = false;

    public function author()
    {
        return $this->hasOne('Authors');
    }

}

My controller then looks like:

 public function authorBooks($name)
    {
        $books = Authors::where('last_name', '=', $name)->get();
        $num = 1;
        $pages = Pages::where('status', '=' , $num)->get();
        $categories = Categories::where('parent_id','=', 0)->get();

        return View::make('site.authorbooks', compact('pages', 'categories', 'books'));

    }

Route

Route::get('/authors/{name}','FrontController@authorBooks');

Then inside my view i call {{ $book->book->first()->title }}

Shows

Trying to get property of non-object (View: /home/vagrant/code/bookstore/app/views/site/authorbooks.blade.php) 

Can anyone help as to where I'm going wrong here?

0 likes
38 replies
bashy's avatar

In your views, you say you use "book->" {{ $book->book->first()->title }} yet you push through "books" compact('pages', 'categories', 'books')

theUnforgiven's avatar

Yeah changed that now to $items to differencite the two, but stil get the same error

theUnforgiven's avatar

Getting Undefined property: Illuminate\Database\Eloquent\Collection::$books now

bashy's avatar

See what you get with

return $books;

In controller before return View::make()

theUnforgiven's avatar

Returns: [{"id":6,"last_name":"Bates","first_name":"H. E."}] which is correct for this particular record

theUnforgiven's avatar

Would it be because the B in bates doesn't match exactly, for example in the url is all lowercase and then in the authors table it has a capital B

arabsight's avatar

your books variable returns a collection of authors, are you looping through it in the view? you are trying to access the "book" hasMany relation from a collection

arabsight's avatar

Try dd($book->books) inside the loop to see if the relation is working

theUnforgiven's avatar

dd($book->books) returns

object(Illuminate\Database\Eloquent\Collection)[359] protected 'items' => array (size=0) empty

bashy's avatar

Is there a relation set? Like, in the actual database

arabsight's avatar

if your collection is empty, and the first() method return null then trying to access title from null will throw

theUnforgiven's avatar

The database(s) are as follows:

Authors Table -- id -- first_name -- last_name

Books Table -- id -- author // This should match the last_name in authors table -- book -- category

arabsight's avatar

dd($book->books) returns: protected 'items' => array (size=0) empty there's no related books. try eager loading:

$books = Authors::with('books')->where('last_name', '=', $name)->get();
return $books;

the returned collection should have a books property with each author

theUnforgiven's avatar

that returns

"[{"id":6,"last_name":"Bates","first_name":"H. E.","books":[]}]"

bashy's avatar

Are you relating your tables via a string for the author?

theUnforgiven's avatar

Passing it like so: <a href="/authors/{{ strtolower($author->last_name) }}"> Which in turn shows as : books.app/authors/bates which then points to the route

bashy's avatar

Yes but in the table? Do you relate the name or the ID from the authors table?

arabsight's avatar

your fields doesn't match. author: "bates (h.e)" != last_name:"Bates"

bashy's avatar

Shouldn't use a dynamic string to relate your relationships, why not use the id field or author_id into Authors table?

theUnforgiven's avatar

becasuse the id in the authors table doesn't match the books table

Next

Please or to participate in this conversation.