Model Doctor
class Doctor extends Model
{
public function addresses() {
return $this->belongsTo(Doctor::class);
}
}
Model Address
class Address extends Model
{
public function doctors() {
return $this->hasMany(Address::class);
}
}
DoctorsController
class DoctorsController extends Controller
{
public function index()
{
$doctors = Doctor::with('addresses')->get();
return view('doctors.index',compact('doctors'));
}
}
Blade
#foreach($doctors as $doctor)
{{ $doctor->name }}
#foreach($doctor->addresses as $address)
{{ $address->city }}
#endforeach
#endforeach
I have an error
Invalid argument supplied for foreach()
I tried to make a relation between Doctor and Address, but it doesn't work. If i try dd($doctor->addresses) i have null.
You reference the same class in your relations ("Doctor belongs to Doctor"), that probably cannot work.
Try:
class Doctor extends Model
{
public function addresses() {
return $this->hasMany(Address::class);
}
}
class Address extends Model
{
public function doctors() {
return $this->belongsTo(Doctor::class);
}
}
does it make sense that a doctor has many addresses and a address has many doctors? basing on your models you do have a many to many relationship between doctors and addresses?
Why not you can do it this way. a doctor has many addresses? so one to many relationship
then your models would be like this way.
Doctor model
class Doctor extends Model
{
public function addresses() {
return $this->hasMany('App\Address','DoctorId');// you need to indicate the foreign key if you didn't follow the laravel naming convention
}
}
address model
class Address extends Model
{
public function doctor() {
return $this->hasOne('App\Doctor','DoctorId');// you need to indicate the foriegn key if you didn't follow the Laravel naming convention
}
}
you controller
class DoctorsController extends Controller
{
public function index()
{
$doctors = Doctor::all();//or Doctor::where('something','=','value')->get();
return view('doctors.index',compact('doctors'));
}
}
your view
#foreach($doctors as $doctor)
{{ $doctor->name }}
#foreach($doctor->addresses as $address)
{{ $address->city }}
#endforeach
#endforeach
Related
I've following relationship:
class Project extends Model
{
public function invitors()
{
return $this->hasMany(Invitation::class)
}
}
// User model
class User extends Model
{
public function invitations()
{
return $this->morphMany('App\Invitation', 'invitee');
}
}
// Business Model
class Business extends Model
{
public function invitations()
{
return $this->morphMany('App\Invitation', 'invitee');
}
}
// Invitation model
class Invitation extends Model
{
public function invitee()
{
return $this->morphTo();
}
public function project()
{
return $this->belongsTo(Project::class);
}
}
What I want is to get project invitors (users, and businesses). When I use from $project->invitors->invitee its not working.
In your example $project->invitors is a collection of Invitation instances, and it hasn't property invitee. You can use helper pluck to loop $project->invitors and get their invitees:
$invitees = $project->invitors->pluck('invitee');
As a response to the first comment:
to get specific attributes of fetched linked models ("invitee") you can specify accessors:
class Business extends Model
{
...
public function getInviteeNameAttribute() {
return $this->name;
}
}
class User extends Model
{
...
public function getInviteeNameAttribute() {
return $this->first_name . ' ' . $this->last_name;
}
}
...then get that attribute from invitee:
$invitees[0]->invitee_name
See https://laravel.com/docs/7.x/eloquent-mutators#defining-an-accessor
I'm trying to print all books' name in 'books' table and its category associated. But it doesn't show any content nor error messages.
Model::Book.php
class Book extends Eloquent{
protected $table ='books';
public function bookCat()
{
return $this->belongsTo('BookCategory');
}
}
Model::BookCategory.php
class BookCategory extends Eloquent{
protected $table ='book_categories';
}
Controller::route.php
Route::get('/', function()
{
$books = Book::all();
return View::make('books')
->with('books', $books);
});
View::books.blade.php
#foreach ($books as $book)
<li>{{ $book->book_name }}</li>
- <small>{{ $book->bookCat }}</small>
#endforeach
Table::books
(int)id, (string)book_name, (int)category_id
Table::book_categories
(int)id, (string)category
Add the relationship to BookCategory.
class BookCategory extends Eloquent{
protected $table ='book_categories';
public function books() {
return $this->hasMany('Book');
}
}
Your local key doesn't match the model names, either, so you would need to specify that in the relation:
class Book extends Eloquent{
protected $table ='books';
public function bookCat()
{
return $this->belongsTo('BookCategory', 'category_id');
}
}
You may also want to eager-load the categories in your controller, as your query is for the books:
$books = Book::with('bookCat')->get();
I have a list of books and a list of authors. I made the Model relations, so that my Book Model says, that books->belongTo('Author') and my Author Model says, that authors->hasMany('Book').
So normally I could access the a variable through this:
$books = Book::all();
And then in the view:
#foreach($books as $book)
<div>{{$book->id}}</div>
<div>{{$book->title}}</div>
<div>{{$book->authors->firstname}}</div>
#endforeach
But this does not work. I get the error message: Trying to get property of non-object
So here are my files:
My Models:
Book.php
class Book extends \Eloquent {
protected $guarded = [];
public function religions()
{
return $this->belongsTo('Religion');
}
public function branches()
{
return $this->belongsTo('Branch');
}
public function authors()
{
return $this->belongsTo('Author');
}
public function quotes()
{
return $this->hasMany('Quote');
}
public function chapters()
{
return $this->hasMany('Chapter');
}
}
Author.php
class Author extends \Eloquent {
protected $guarded = [];
public function books()
{
return $this->hasMany('Book');
}
public function quotes()
{
return $this->hasMany('Quote');
}
public function branches()
{
return $this->belongsTo('Branch');
}
public function religions()
{
return $this->belongsTo('Religion');
}
}
Then come my controller:
ReligionBranchBookController
class ReligionBranchBookController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index($religionId, $branchId)
{
//
// $books = Book::where('religion_id', $religionId)->where('branch_id', $branchId)->get();
$books = Book::all();
$authors = Author::all();
// dd($books->toArray());
return View::make('books.index')
->with('religionId', $religionId)
->with('branchId', $branchId)
->with('books', $books)
->with('authors', $authors);
}
}
My Views:
index.blade.php
#extends('layout.main')
#section('content')
<h1>Books List!!</h1>
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Author</th>
</tr>
#foreach($books as $book)
<tr>
<td>{{$book->id}}</td>
<td>{{$book->title}}</td>
<td>{{$book->authors->firstname}}</td>
</tr>
#endforeach
</table>
#stop
I know that it should normally work, I rebuild it with only books and authors, and it works fine there.
So, does anyone have an idea, where I am going wrong?
Thanks,
George
In your Book model change the authors method to author like this:
public function author()
{
return $this->belongsTo('Author');
}
Because, one book belongs to one author according to your relationship and when you call authors the belongsTo->getResults() get called and runs the wrong query so authors get null and you get the error. Things to remember:
For hasOne and belongsTo relationship use singular form of relationship method, i.e, author not authors.
hasOne or belongsTo returns a single model object.
For hasMany and belongsToMany relationship use plural form of relationship method, i.e, authors not author.
hasMany and belongsToMany returns a collection of model objects.
I have a database with the following tables and relationships:
Advert 1-1 Car m-1 Model m-1 Brand
If I want to retrieve an Advert, I can simply use:
Advert::find(1);
If I want the details of the car, I could use:
Advert::find(1)->with('Car');
However, if I also want the detail of the Model (following the relationship with Car), what would the syntax be, the following doesn't work:
Advert::find(1)->with('Car')->with('Model');
Many thanks
It's in the official documentation under "Eager Loading"
Multiple relationships:
$books = Book::with('author', 'publisher')->get();
Nested relationships:
$books = Book::with('author.contacts')->get();
So for you:
Advert::with('Car.Model')->find(1);
First you need to create your relations,
<?php
class Advert extends Eloquent {
public function car()
{
return $this->belongsTo('Car');
}
}
class Car extends Eloquent {
public function model()
{
return $this->belongsTo('Model');
}
}
class Model extends Eloquent {
public function brand()
{
return $this->belongsTo('Brand');
}
public function cars()
{
return $this->hasMany('Car');
}
}
class Brand extends Eloquent {
public function models()
{
return $this->hasMany('Model');
}
}
Then you just have to access this way:
echo Advert::find(1)->car->model->brand->name;
But your table fields shoud be, because Laravel guess them that way:
id (for all tables)
car_id
model_id
brand_id
Or you'll have to specify them in the relationship.
Suppose you have 3 models region,city,hotels and to get all hotels with city and region then
Define relationship in them as follows:-
Hotel.php
class Hotel extends Model {
public function cities(){
return $this->hasMany(City::class);
}
public function city(){
return $this->belongsTo('App\City','city_id');
}
}
City.php
class City extends Model {
public function hotels(){
return $this->hasMany(Hotel::class);
}
public function regions(){
return $this->belongsTo('App\Region','region_id');
}
}
Region.php
class Region extends Model
{
public function cities(){
return $this->hasMany('App\City');
}
public function country(){
return $this->belongsTo('App\Country','country_id');
}
}
HotelController.php
public function getAllHotels(){
// get all hotes with city and region
$hotels = Hotel::with('city.regions')->get()->toArray();
}
will adding the relation function just ask for the relation needed
public function Car()
{
return $this->belongsTo(Car::class, 'car_id')->with('Model');
}
but if you want a nested relation just use the period in the with
Advert::with('Car.Model')->find(1);
but for multi-relation use the array
Advert::with('Car','Model')->find(1);
I have two table User & Article the relationship between tables are
Model:
class Article extends Eloquent {
public static $table = 'article';
public function User()
{
return $this->has_one('user', 'id');
}
and
class User extends Eloquent {
public static $table = 'user';
public function Article()
{
return $this->belongs_to('article', 'id_user');
}
I want to get name value from User directly on Article view but don't works with error
Trying to get property of non-object
My Controller:
public function action_index()
{
$Article = Article::order_by('id')->paginate(10);
return View::make('article.index')->with('$articles', $Article);
}
My View:
#foreach ($articles->results as $Arti)
<tr>
<td>{{$Arti->id}}</td>
<td>{{$Arti->tag}}</td>
<td>{{$Arti->user->name }}</td> <------ ERROR
<td>{{$Arti->content}}</td>
<td>{{$Arti->date}}</td>
<td>
Have a look at the below, a few things are different to yours...
Article belongs_to User (not has_one)
User has_many Article (not belongs_to)
Your relationships should be named in lowercase, plural for has_many (i.e. articles or user)
Your relationship subjects should be class names (i.e. Article or User)
Foreign keys should be name relationship_id, i.e. user_id
Add ::with() to your query to eager load relationships
When you paginate you need to access ->results in your view
class Article extends Eloquent {
// 3: lowercase 'user'
public function user()
{
// 1: Article belongs to User
// 4: class name 'User'
// 5: Foreign key on article table is user_id
return $this->belongs_to('User');
}
}
// models/user.php
class User extends Eloquent {
// 3: lowercase plural 'articles'
public function articles()
{
// 2: User has many Articles
// 4: class name 'Article'
return $this->has_many('Article');
}
}
// controllers/articles.php
class Article_Controller extends Base_Controller {
public $restful = true;
public function get_index()
{
// 6: Eager load the user relationship, ::with('user')
$articles = Article::with('user')->order_by('id')->paginate(10);
return View::make('articles.index', compact('articles'));
}
}
// views/articles/index.blade.php
// 7: access $articles->results from the paginator
#foreach ($articles->results as $article)
<h1>{{ $article->title }}</h1>
<p>By {{ $article->user->name }}</p>
#endforeach
{{ $articles->links() }}