Полиморфные яркие отношения с пространствами имен

Я попытался реализовать полиморфные отношения. Они отлично работают... Тем не менее, я стараюсь как можно меньше уменьшить размер базы данных, поэтому... Я это

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.