Reputation: 141
I want to define a relationship between tables, and I don't know where I'm going wrong.
These are my tables:
users
-id -email -level
restaurants
-id -name -user_id
menus
-id -name
restaurant_menu
-restaurant_id -menu_id -price
In the users
table, the field level
will set by me with two words: [user]
or [restaurant]
.
User Model
public function restaurant(){
return $this->hasOne(Restaurant::class);
}
Restaurant Model
public function menus(){
return $this->hasMany(Menu::class);
}
Menu Model
public function restaurants(){
return $this->belongsTo(Restaurant::class);
}
I expect the output of this code:
$result = $restaurant->where('id',2)->menus()->get();
To be records and relations, but i get the following error.
BadMethodCallException Call to undefined method Illuminate\Database\Eloquent\Builder::menus()
What should I do?
Upvotes: 4
Views: 18576
Reputation: 158
IN user model
public function restaurant(){
return $this->hasMany(Restaurant::class,'user_id','id');
}
Restaurant model
public function menus(){
return $this->hasMany(Menu::class,'id','menu_id');
}
Menu model
public function restaurants(){
return $this->belongsTo(Restaurant::class);
}
As you aspect your output you need to write
$result = Restaurant::with('menus')->where('id',2)->get();
you will get relational data. Like which restaurants has which menus.
You also can use this for your scenario. Use this in your Restaurant model
public function menues(){
return $this>hasManyThrough(Menu::class,restaurant_menu::class,'menu_id','id','id','restaurant_id');
}
Upvotes: 4
Reputation: 1410
Relations you define are not available for you in the query scope of your builder instance the way you tried to call them. They are available in the context of your models. Including your relationships in the queries is done differently - you should check official documentation on the matter first.
In your case, if you want to select all menus that belong to specific restaurant you have to ways:
You can first fetch specific restaurant and then get it's menus via a relationship:
$restaurant = Restaurant::find(2);
$menus = $restaurant->menus;
You can query for menus via Menu
model:
$menus = Menu::whereHas('restaurants', function ($query) {
$query->where('id', 2);
})-get();
Also your relations are set up wrong. Based on table structure you've provided your menus and restaurants are in many-to-many relationship. Therefore restaurants()
relation method in Menu
class needs to return BelongsToMany
instance. So while you're at it I would strongly suggest for you to go over relationships documentation and watch examples until you get the concepts of how different relationships work in Laravel.
Upvotes: 3
Reputation: 1536
There is a problem with your relationship. You have a one to many relationship between restaurant model and menu model. However, your table structure suggests that, they have a many to many model.
If you think your model is right then change the menus table in following way,
menus
-id
-name
-restaurant_id //new field
Also, delete the "restaurant_menu" table.
If you think your database is correct then try changing the model accordingly.
Upvotes: 0
Reputation: 684
Actually,
you defined relations in a correct way. I think that, you have an issue about to get those relations on the eloquent queries. If you want to get menu relation of a specific restaurant; you have to implement something like that.
$restaurant = Restaurants::find(2);
$restaurant->menus(); // this will return an array of related menus.
You should read Laravel Offical documentation. There are Retrieving The Relationship headlines for each relationship definition.
Upvotes: 0