Полиморфные яркие отношения с пространствами имен
Я попытался реализовать полиморфные отношения. Они отлично работают... Тем не менее, я стараюсь как можно меньше уменьшить размер базы данных, поэтому... Я это
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 { ... }
Есть ли способ сохранить только "Люди" или "Компания", предполагая, что пространство имен всегда будет "Lion"?
Ответы
Ответ 1
Начиная с Laravel 4.1 внутри вашей модели (в данном случае Компания и Люди) вы можете установить защищенное свойство $morphClass
на все, что хотите.
<?php namespace Lion;
class Company extends \Eloquent {
protected $morphClass = 'Company';
}
Теперь в вашей таблице вы можете сохранить тип без пространства имен:
| id | realatable_type | relatable_id
| 2 | Company | 13
Ответ 2
Я считаю, что лучшее решение здесь (по крайней мере, для размера базы данных) - это просто изменить readable_type
на ENUM('Lion\Company', 'Lion\People')
.
Если вы действительно хотите обработать это на стороне Laravel, вам придется создавать новые классы, простирающиеся от Illuminate\Database\Eloquent\Relations\Morph*
¹ и перезаписывать их конструкторы ², чтобы получить только последнее значение после тире, на $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
.