2016-12-02 43 views
-2

在我的數據庫中,我有一個表form_fields具有這樣的結構:Laravel - 動態雄辯型號取決於列值

id | form_id | title | type 
1 | 1  | Subject | text 
2 | 1  | Enquiry | textarea 
3 | 1  | Logo | file 

我有FormFormField車型,這樣的關係從Form

public function fields() 
{ 
    return $this->hasMany('App\Modules\Forms\Models\FormField', 'form_id', 'id'); 
} 

現在是否可以根據type字段更改使用哪個類?所以如果我有TextFormField,TextareaFormFieldFileFormField,所有擴展基地FormField模型,是否有可能得到Laravel使用這些?或者我必須手動完成,所以獲取字段,遍歷它們,並基於類型創建新的實例?這似乎並不困難,但它似乎是一種浪費資源,好像我有20個字段,20個FormField實例將被創建,然後我將手動創建20個以上?

謝謝!

回答

1

在一個關係,你不能,因爲當你訪問你的領域

foreach($form->fields as $field) { ... } 

您已經通過$this->hasMany(...),它走了,你不能爲每場提供不同的類。

你可以做的就是你的對象重鑄到適當的類,你得到它後,做這樣的事情:

這是施工實例

Route::get('debug/cast', function() { 
    $form = collect([['type' => 'text', 'name' => 'address'], ['type' => 'date', 'name' => 'birthdate']]); 

    $fields = FieldTypeCollection::make($form->toArray()); 

    dd($fields); 
}); 

class FieldTypeCollection extends Collection 
{ 
    public function __construct($items) 
    { 
     parent::__construct($items); 

     if (is_array($items)) { 
      $this->recastAll(); 
     } 
    } 

    private function recastAll() 
    { 
     $items = []; 

     foreach ($this->items as $key => $item) { 
      $items[] = (new FieldFactory())->make($item); 
     }; 

     $this->items = $items; 
    } 
} 

class FieldFactory 
{ 
    public function make($field) 
    { 
     if ($field['type'] == 'date') { 
      $new = new DateInputFieldType(); 
     } else { 
      $new = new TextInputFieldType(); 
     } 

     return $this->importData($field, $new); 
    } 

    private function importData($old, $new) 
    { 
     $new->type = $old['type']; 

     $new->name = $old['name']; 

     return $new; 
    } 
} 

class TextInputFieldType 
{ 
    public $type; 

    public $name; 
} 

class DateInputFieldType 
{ 
    public $type; 

    public $name; 
} 

你會得到這樣的結果:

enter image description here

+0

不會是easyer來覆蓋模式類似(psuedoco get方法de)函數get(){返回SomeClassname :: where(type,classId)} - > get(); –