Reputation: 61
I try to create relations between different tables in my database and get data from these tables, but I got an error: Property does not exist on this collection instance.
This is my code:
Migrations files:
Schema::table('books', function (Blueprint $table) {
$table->foreignId('author_id')->constrained('authors')->onUpdate('cascade')->onDelete('cascade');
});
In Model\Authors:
public function books () {
return $this->hasMany('App\Models\Books');
}
In Model\Books:
public function author() {
return $this->belongsTo('App\Models\Authors');
}
In AuthorsController:
public function index () {
$authors = Authors::all();
return dd($authors->books);
}
In BooksController:
public function index () {
$books = Books::all();
return dd($books->author);
}
If someone has an idea how to fix this, I will be very grateful.
Upvotes: 0
Views: 102
Reputation: 61
Thank you guys! In my case, the right solution was :
In model:
public function author() { return $this->belongsTo('App\Models\Authors', 'author_id'); }
And in controller :
$books = Books::with('author')->get();
And in view file I added:
@foreach
<li>{{ $book->title}}</li>
<li>{{ $book->author->name}}</li>
@endforeach
Thank you again. The topic can be closed )))))
Upvotes: 0
Reputation: 17206
If you want to have all authors with their books, use eager loading with()
public function index () {
$authors = Authors::with('books')->get();
return dd($authors);
}
If you wants all the books with their respective author
public function index () {
$books = Books::with('author')->get();
return dd($books);
}
When you iterate the collection (like an array) in your blade, you can then access the relation
@foreach($books as $book)
<span>{{$book->author->name}}</span>
@endforeach
If you just want to get a dd of the books of one author you can do it like this
public function index () {
$authors = Authors::all();
// $authors is a collection of models (think of it as an advanced array)
// To get one of the models, you can iterate them with a loop or, for example, take the first one with "->first()"
//$authors->first() is an instance of the model "Author" class
return dd($authors->first()->books);
// $authors->first()->books is now a collection of models of "Book" class
}
Upvotes: 1
Reputation: 8338
Your relation between Authors and books is one-to-many so an Author hasMany
books (like you have correctly stated in the model relation).
The output of this is a collection so you can not access it that way, instead you need to loop it like:
public function index () {
$authors = Authors::all();
$authors->books->each(function ($book) {
print_r($book);
}
}
In case you want to retrieve the books of a single Author you can return a single model instance for the Author like:
public function index () {
$author = Authors::where('id',1)->first();
print_r($author->books);
}
Upvotes: 0
Reputation: 966
Your models is right but you wrong when you call $authors->books because $authors is collection of your Authors model not object of Author. If your want check your relationship you can do with this example:
public function index () {
$authors = Authors::latest()->first();;
dd($authors->books);
}
Upvotes: 1