Search code examples
laravel-4eloquentlaravel-5polymorphic-associationsrelationships

Polymorphic relations in upgraded Laravel app from 4.2 to 5


Short: some related models are returning instances correctly, but some aren't (the polymorphic ones).

I have those three models:

app/Models/User.php

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function company()
    {
        return $this->hasOne('App\Company');
    }
}

app/Models/Company.php

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Company extends Model {

    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function address()
    {
        // Also tested with morphMany, without success
        return $this->morphOne('App\Address', 'addressable');
    }

}

app/Models/Address.php

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Address extends Model {

    public function addressable()
    {
        return $this->morphTo();
    }

}

And the controller:

app/Http/Controllers/MyController.php

<?php namespace App\Http\Controllers;

// ... many "use" clauses not relevant to the question
use Auth;
// ...

use App\Address;
use App\Company;
use App\User;

class MyController extends Controller {

    // Ok here
    $user = Auth::user();

    // Ok here, too
    $company    = $user->company()->first();

    // Here is the problem; $address is null
    $address    = $company->address()->first();

}

The line $company->address()->first(); is always returning null to $address in Laravel 5, but it worked well in Laravel 4.2


Solution

  • In L4 models were not namespaced by default, so they were saved as ModelName in your table, while now in L5 they are rather Namespace\ModelName and are retrieved the same way.

    That said, your data saved in L4 needs to be adjusted so it matches your current models, or you can use protected $morphClass on the models.

    However take this into consideration for the latter solution.