我试图实现多态关系。它们完美地工作......但是,我正在尽可能地减少我的数据库大小,所以......我已经这样了
Table action
| id | realatable_type | relatable_id
| 1 | Lion\People | 65
| 2 | Lion\Company | 13
显然我有这个
<?php namespace Lion;
class Company extends \Eloquent { ... }
class People extends \Eloquent { ... }
有没有办法只存储“人”或“公司”,假设命名空间总是“狮子”?
答案 0 :(得分:23)
从Laravel 4.1开始,在您的模型中(在本例中为公司和人),您可以将受保护的属性$morphClass
设置为您想要的任何内容。
<?php namespace Lion;
class Company extends \Eloquent {
protected $morphClass = 'Company';
}
现在,在您的表中,您可以存储没有命名空间的类型:
| id | realatable_type | relatable_id
| 2 | Company | 13
答案 1 :(得分:3)
我认为这里的最佳解决方案(至少对于数据库大小)只需将readable_type
更改为ENUM('Lion\Company', 'Lion\People')
。
话虽如此,如果你真的想在Laravel方面处理这个问题,你必须创建从Illuminate\Database\Eloquent\Relations\Morph*
¹扩展的新类并覆盖它们的构造函数²< / strong>仅在$morphClass
上获得短划线后的最后一个值。像这样:
<?php
use \Illuminate\Database\Eloquent\Model;
use \Illuminate\Database\Eloquent\Builder;
class MyMorphOne extends \Illuminate\Database\Eloquent\Relations\MorphOne {
public function __construct(Builder $query, Model $parent, $type, $id) {
parent::__construct($query, $parent, $type, $id);
$this->morphClass = substr($this->morphClass, strrpos($this->morphClass, '\\') + 1);
}
}
然后,扩展您自己的模型或基本模型,以覆盖morphOne
,morphMany
和morphToMany
方法,以便使用新的扩展类。像这样:
<?php
class People extends Eloquent {
// ...
public function morphOne($related, $name, $type = null, $id = null) {
$instance = new $related;
list($type, $id) = $this->getMorphs($name, $type, $id);
$table = $instance->getTable();
return new MyMorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id);
}
}
*
= One
,Many
和ToMany
MorphOneOrMany
和MorphOne
上的MorphMany
继承的。