Laravel 5 "Trying to get property of non-object" error when passing multiple join table values to view

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Solving the "Trying to get property of non-object" Error: Mastering Joins and Eloquent Relationships in Laravel

As developers working with relational databases in Laravel, dealing with complex data retrieval often involves joining multiple tables. While powerful, this process can easily lead to subtle errors, such as the dreaded ErrorException: Trying to get property of non-object, especially when passing results to Blade views.

This post dives into a common pitfall encountered when mixing raw database queries (using joins) with Eloquent models and attempting to access nested properties in your view layer. We will analyze the scenario you presented and demonstrate the robust, idiomatic Laravel solution.

The Root of the Problem: Flat Data vs. Object Structure

The error arises because of a fundamental difference between how raw SQL joins return data and how Eloquent objects are structured.

In your controller, you used the DB facade to perform explicit join operations:

$text = DB::table('pages')
    ->where('pages.id', '=', $id)
    ->join('texts', 'pages.id', '=', 'texts.page_id')
    ->join('users', 'pages.user_id', '=', 'users.id')
    ->get();

This query returns a flat array of results, where each element is an associative array containing columns from all three joined tables (e.g., title, username, content). It does not return a hydrated Eloquent model object that understands the nested relationships defined in your models (User hasMany Page, Page hasMany Text).

When you later try to access $text->username in your view, PHP attempts to treat this flat array as an object, leading to the error because the array structure does not have a property named username.

The fact that simply returning $text (the JSON response) worked confirms this: you were correctly retrieving the raw data, but you lost the object context necessary for dot notation access.

The Laravel Best Practice: Embracing Eloquent Relationships

In Laravel, when dealing with hierarchical data, the most effective and maintainable approach is to leverage Eloquent's built-in relationships rather than manually writing complex SQL joins in the controller. This keeps your business logic within the Models, adhering to the principles of Object-Relational Mapping (ORM).

Instead of joining tables directly, we should let Eloquent handle the relationship loading using the with() method for eager loading. This ensures that when you retrieve a parent model (like a Page), all related data (like its associated Text content and the User who owns it) are loaded into proper, navigable object structures.

Refactoring the Controller Logic

The solution involves querying the primary model and eagerly loading all necessary relationships. This shifts the responsibility of joining and structuring the data from the controller to the Model, which is where it belongs.

If you were fetching a Page record:

// Instead of complex joins in the controller:
public function show($id)
{
    // Fetch the Page model and eager load its relationships (texts and user)
    $page = Page::with('texts', 'user')->findOrFail($id);

    return view('app.text', compact('page')); // Pass the fully hydrated object
}

By passing the $page object to the view, you can safely access nested data using standard object notation:

{{-- Accessing related data safely --}}
<h1>{{ $page->texts->first->title }}</h1>
<p>User: {{ $page->user->username }}</p>

This pattern is central to effective data management in the Laravel ecosystem. For deeper dives into how Eloquent manages these relationships and query optimization, explore resources on the official Laravel documentation at https://laravelcompany.com.

Conclusion

The "Trying to get property of non-object" error when dealing with joins is a symptom of trying to force flat database results into an object structure that expects nested relationships. The correct solution in Laravel is to prioritize Eloquent's ORM capabilities. By using with() for eager loading, you delegate the complex joining and data structuring to the framework, resulting in cleaner, more predictable, and significantly easier-to-maintain code. Always aim to work with fully hydrated Eloquent models rather than raw, flat arrays when rendering views.