How to Define Relations and Get All Records with Relations in Laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# How to Define Relations and Get All Records with Relations in Laravel: Solving the `BadMethodCallException`
As a senior developer working with Laravel, defining relationships between Eloquent models is fundamental to building scalable and maintainable applications. It’s incredibly common to run into issues when setting up these connections—especially when dealing with pivot tables or complex many-to-many scenarios. The error you encountered, `BadMethodCallException: Call to undefined method Illuminate\Database\Eloquent\Builder::menus()`, usually signals that the relationship method hasn't been correctly defined on the model, or the underlying foreign key structure isn't recognized by Eloquent.
This post will walk through exactly how to define these relationships based on your provided schema and demonstrate the correct way to query related data in Laravel. We will fix the issue so you can efficiently retrieve all menus for a specific restaurant.
## Understanding Database Relations (The Foundation)
Before touching the code, let's look at the relational structure implied by your tables:
* **`users`**: Stores user information.
* **`restaurants`**: Stores restaurant details, linked to a user via `user_id`.
* **`menus`**: Stores menu items.
* **`restaurant_menu` (Pivot Table)**: Links restaurants and menus, storing the price (`restaurant_id`, `menu_id`, `price`).
The relationship between restaurants and menus is many-to-many, facilitated by the pivot table `restaurant_menu`. This means a restaurant can have many menus, and a menu can belong to many restaurants.
## Defining Eloquent Relationships Correctly
The key to resolving your error lies in correctly defining the methods within your Eloquent models (`Restaurant` and `Menu`). We use the foreign keys and the pivot table structure to establish these links.
### 1. The Restaurant Model
A restaurant has many menu entries via the pivot table. Therefore, we define a `hasMany` relationship from the `Restaurant` model to the junction table.
```php
// app/Models/Restaurant.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Restaurant extends Model
{
// Relationship to Users (One-to-One/Many-to-One)
public function user()
{
return $this->belongsTo(User::class);
}
// Relationship to Menus (Many-to-Many via pivot table)
public function menus(): HasMany
{
// This points to the junction table where the relationship is defined.
return $this->belongsToMany(Menu::class);
}
}
```
### 2. The Menu Model
Similarly, the `Menu` model needs a `belongsToMany` relationship back to the `Restaurant`.
```php
// app/Models/Menu.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Menu extends Model
{
public function restaurants(): BelongsToMany
{
return $this->belongsToMany(Restaurant::class);
}
}
```
**Why this works:** By defining these methods using Eloquent's relationship helpers (`hasMany`, `belongsTo`, `belongsToMany`), Laravel automatically knows how to construct the necessary SQL joins when you call these methods on an Eloquent instance. This is a core concept discussed extensively in the official documentation, like the guides found on https://laravelcompany.com regarding Eloquent specifics.
## Retrieving Data with Defined Relations
Once the relationships are correctly defined on both sides of the models, querying becomes straightforward and highly expressive. Your original attempt failed because Laravel could not find the method named `menus()` on the `Restaurant` builder object. It now can.
To get all menus for a specific restaurant (assuming you have retrieved the `$restaurant` instance):
```php
use App\Models\Restaurant;
// Assume $restaurant is an instance of Restaurant with ID 2
$restaurant = Restaurant::find(2);
if ($restaurant) {
// Correct way to retrieve all related menus
$menus = $restaurant->menus()->get();
// Or, using eager loading for optimal performance (highly recommended!)
$restaurantWithMenus = Restaurant::with('menus')->find(2);
}
```
### Best Practice: Eager Loading
Notice the difference between `$restaurant->menus()->get()` and `Restaurant::with('menus')->find(2)`. While the first approach works, it executes two separate database queries (one for the restaurant, one for the menus). The second approach uses **Eager Loading** (`with('menus')`), which instructs Eloquent to fetch the related data in a single, optimized query using a `JOIN`, significantly improving performance.
## Conclusion
Defining relations is about accurately mapping your database structure into object-oriented code. By strictly defining `hasMany` and `belongsToMany` relationships based on your foreign keys and pivot tables, you enable Eloquent to build the necessary query methods. Always review how your models interact with the underlying schema; this disciplined approach will prevent method call errors and lead you toward cleaner, more efficient Laravel applications.