2013-11-09 55 views
10

我試圖實現多態關係。他們很好地工作......不過,我想減少我的數據庫大小,儘可能使......我這個與名稱空間的多態性雄辯關係

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 { ... } 

有沒有任何只存儲「People」或「Company」的方式都假設命名空間永遠是「Lion」?

+2

有這樣做的一種方式,但它需要相當一些工作,它可能不是你的數據庫的最佳解決方案尺寸問題。您是否考慮將'readable_type'轉換爲'ENUM('Lion \ People','Lion \ Company')'字段? – rmobis

+0

@Raphael_我不得不承認,我期待的是雄辯的解決方案,但這個看起來像一個可能性......:D –

+0

這實際上比只有'人'或'公司'佔用的空間更小。如果你真的想要雄辯的解決方案,讓我知道,我會發布它。 – rmobis

回答

23

由於Laravel 4.1,你的模型內(在這種情況下公司),您可以設置保護屬性$morphClass到任何你想要的。

<?php namespace Lion; 

class Company extends \Eloquent { 

    protected $morphClass = 'Company'; 
} 

現在,在你的表,你可以存儲的類型沒有命名空間:

| id | realatable_type | relatable_id 
| 2 | Company   | 13 
+0

不知道這個...真的很好的答案,非常感謝你) –

+1

在Laravel 5.3 $ morphClass屬性有已被刪除。現在你需要使用'Relation :: morphMap(['company'=> Company :: class]);' –

3

我相信這裏最好的解決方案(對於數據庫大小至少)應該是簡單地將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); 
    } 
} 

然後,延長自己的模型或示範基地,覆蓋morphOnemorphManymorphToMany方法來利用你的新的擴展類。事情是這樣的:

<?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); 
    } 

} 
  1. * = OneMany和這實際上是從MorphOneOrMany繼承了MorphOneMorphManyToMany