Laravel 应用程序从 4.2 升级到 5 时的多态关系
Polymorphic relations in upgraded Laravel app from 4.2 to 5
简短:一些相关模型正确返回实例,但有些不是(多态模型)。
我有这三个模型:
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();
}
}
控制器:
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();
}
行 $company->address()->first();
总是在 Laravel 5 中返回 null
到 $address
,但它在 Laravel 4.2
中运行良好
如果您打开数据库 - 您会看到旧 L4 数据中的关系存储为:User
或 Company
您需要 运行 一个脚本来将列更新为新的命名空间名称 - 例如 App\User
或 App\Company
这是因为您现在正在为您的模型命名空间 - 所以 Laravel 需要知道要调用哪个命名空间。
连同@The Shift Exchange 的回答并按照我的问题示例,您可以关注 this approach:
不是在 address
table 的 addressable_type
列值中添加名称空间(这是一个有效的解决方案),您可以使用 $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');
}
在 L4 中模型默认没有命名空间,因此它们在您的 table 中保存为 ModelName
,而现在在 L5 中它们更像是 Namespace\ModelName
并且以相同的方式检索.
也就是说,您保存在 L4 中的数据需要调整以匹配您当前的模型,或者您可以在模型上使用 protected $morphClass
。
但是,对于后一种解决方案,请考虑 。
简短:一些相关模型正确返回实例,但有些不是(多态模型)。
我有这三个模型:
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();
}
}
控制器:
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();
}
行 $company->address()->first();
总是在 Laravel 5 中返回 null
到 $address
,但它在 Laravel 4.2
如果您打开数据库 - 您会看到旧 L4 数据中的关系存储为:User
或 Company
您需要 运行 一个脚本来将列更新为新的命名空间名称 - 例如 App\User
或 App\Company
这是因为您现在正在为您的模型命名空间 - 所以 Laravel 需要知道要调用哪个命名空间。
连同@The Shift Exchange 的回答并按照我的问题示例,您可以关注 this approach:
不是在 address
table 的 addressable_type
列值中添加名称空间(这是一个有效的解决方案),您可以使用 $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');
}
在 L4 中模型默认没有命名空间,因此它们在您的 table 中保存为 ModelName
,而现在在 L5 中它们更像是 Namespace\ModelName
并且以相同的方式检索.
也就是说,您保存在 L4 中的数据需要调整以匹配您当前的模型,或者您可以在模型上使用 protected $morphClass
。
但是,对于后一种解决方案,请考虑