Call to undefined relationship [companies] on model [App\Models\Announcement]. How can I solve this
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Solving the Mystery: Call to undefined relationship [companies] on model [App\Models\Announcement]
As a senior developer working with Laravel and Eloquent, dealing with database relationships is fundamental. When you encounter an error like "Call to undefined relationship," it usually points to a mismatch between how you defined your models and how you are trying to access the data through your controller or views.
Today, we will walk through a common scenario where developers run into this exact issue while trying to eager load related data. We will diagnose the problem in your setup and provide the definitive solution, ensuring your application adheres to Eloquent best practices.
The Problem Diagnosis: Why is the Relationship Undefined?
The error message Call to undefined relationship [companies] on model [App\Models\Announcement] clearly states that the Announcement model does not know how to load a relationship named companies.
Let's review your provided setup:
- Database Structure: You have an
announcementstable with acompany_id, linking it to thecompaniestable. This is a classic many-to-one relationship (many announcements belong to one company). - The Controller Attempt: You are trying to load data using:
$announcement = Announcement::orderBy('id','desc')->with('companies')->get();. The use ofwith('companies')tells Eloquent to fetch the related data efficiently (eager loading). - The Model Definitions:
- In your
Announcementmodel, you defined a relationship namedcompany()usingbelongsTo(Company::class, 'company_id'). - Crucially, you did not define a relationship called
companies.
- In your
Eloquent strictly relies on the methods you explicitly define in your models. Since no method named companies exists on the Announcement model, Laravel throws an error when it attempts to resolve that call during the database query execution.
The Solution: Defining Correct Eloquent Relationships
The solution lies in ensuring your model relationships accurately reflect the underlying database structure and the data you intend to retrieve. We need to rename the relationship to match the actual connection defined in the database (which is company) and ensure we use the correct naming conventions for eager loading.
Step 1: Correcting the Announcement Model
Since an announcement belongs to one company, the correct relationship type is belongsTo. We will use the name company as established in your initial setup.
// app/Models/Announcement.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Announcement extends Model
{
protected $table = 'announcements';
/**
* Define the relationship: An announcement belongs to a company.
*/
public function company()
{
// This correctly maps the foreign key 'company_id' in the announcements table
return $this->belongsTo(Company::class);
}
// Optional: If you need a way to access the company name directly, use accessor methods.
public function getCompanyAttribute()
{
// Accessing the related model via the defined relationship
return $this->company ? $this->company->name : null;
}
}
Step 2: Correcting the Company Model (For completeness)
Your setup for the Company model correctly defines the inverse relationship using hasMany. This is perfect for querying announcements from a company.
// app/Models/Company.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
protected $table = 'companies';
/**
* Define the relationship: A company has many announcements.
*/
public function announcements()
{
return $this->hasMany(Announcement::class, 'company_id');
}
}
Step 3: Adjusting the Controller Logic
Now that the Announcement model knows how to find its related Company, you need to adjust your controller query. If you want to load the company details alongside the announcements, you use the relationship name (company) in the with() method.
// app/Http/Controllers/AnnouncementController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Announcement; // Ensure this is imported
use App\Models\Company; // Import Company if needed for other queries
class AnnouncementController extends Controller
{
public function upcomingIssues()
{
// Fetch announcements, eager loading the 'company' relationship.
$announcements = Announcement::orderBy('id', 'desc')
->with('company') // Correctly load the defined relationship
->get();
return view('pages.upcoming-issues', compact('announcements'));
}
}
Best Practices for Eloquent Relationships
Understanding these relationships is key to efficient data retrieval in Laravel. Always remember:
- Explicit Definitions: Never assume a relationship exists. Always define
belongsTo,hasOne,belongsToMany, orhasManyin your models. This is the foundation of robust application development, as promoted by resources like those found on laravelcompany.com. - Naming Conventions: Use clear, descriptive names for your relationships (e.g.,
companyinstead ofcompanies). - Eager Loading (
with()): Always use eager loading when retrieving related models in a loop or collection. This prevents the N+1 query problem, where you execute one query for the main records and then $N$ additional queries to fetch the relationships individually.
Conclusion
The "Call to undefined relationship" error is a clear signal that your Eloquent model definitions need alignment with your database structure and your retrieval logic. By correctly defining the belongsTo relationship in the Announcement model and using the correct relationship name (company) within your controller's with() clause, you resolve the issue and build a more efficient and maintainable application. Keep mastering these concepts; they are central to writing high-quality Laravel code!