0

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

Paulo Coghi
  • 13,724
  • 14
  • 68
  • 90

3 Answers3

1

If you open your database - you'll see the relationship in your old L4 data stored as: User or Company

You need to run a script that updates the columns to the new namespace names - such as App\User or App\Company

This is because you are now namespacing your models - so Laravel needs to know which namespace to call.

Laurence
  • 58,936
  • 21
  • 171
  • 212
  • In `address` table, I have updated each row data in `addressable_type` column, but no success. – Paulo Coghi Mar 27 '15 at 16:59
  • Your solution seems to be right, but I can't get it to work. Then, I tried `morphClass` from @JarekTkaczyk suggestion, and it worked perfectly. – Paulo Coghi Mar 27 '15 at 17:12
1

Along with @The Shift Exchange's answer and following my question's example, you can follow this approach:

Instead of adding the namespace in addressable_type column values from address table (and this is a valid solution), you can use $morphClass:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Company extends Model {

    protected $morphClass = 'Company';

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

    public function address()
    {
        // Also tested with morphMany, without success
        return $this->morphOne('App\Address', 'addressable');
    }
Community
  • 1
  • 1
Paulo Coghi
  • 13,724
  • 14
  • 68
  • 90
1

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.

Community
  • 1
  • 1
Jarek Tkaczyk
  • 78,987
  • 25
  • 159
  • 157