2016-02-15 12 views
1

Не совсем ясно, как это было в первый раз, когда я возился с этим. Моя структура таблицы выглядит следующим образом:Laravel 5 Полиморфные отношения

questions 
- id 
- type_id 

multiple_choice_options 
- id 
- question_id 

drag_and_drop_options 
- id 
- question_id 

type_id поле на questions таблице определяет, какие параметры таблицы для загрузки с. Таким образом, по существу, я хотел бы установить отношения на Question модели следующим образом:

class Question extends Model { 
    public function options() { 
     // not sure what to return here? 
    } 
} 

И для моделей опционных это было бы правильное обратное определение?

class MultipleChoiceOption extends Model { 
    public function question() { 
     return $this->belongsTo(Question::class); 
    } 
} 

class DragAndDropOptions extends Model { 
    public function question() { 
     return $this->belongsTo(Question::class); 
    } 
} 

Как настроить это для работы с полиморфными отношениями?

ответ

0

Вы можете просто создать переключатель в options() отношении:

class Question extends Model { 
    public function options() { 
     if ($type_id === 'multiple') { 
      return $this->hasMany(MultipleChoiceOption::class); 
     } else { 
      return $this->hasMany(DragAndDropOptions::class); 
     } 
    } 
} 

Осторожны с этими волшебными отношений, вам потребуются дополнительные проверки типа и тщательного кодирования в вашем приложении.

+0

Чтобы быть честным, я надеялся избежать использования переключателя, так как существует около 10 различных типов вопросов. Что касается приложения, я планировал использовать коммутатор в любом случае, чтобы включить различные лезвия для каждого типа вопросов. – thorne51

+0

Закончено с использованием этого решения, кроме как с помощью переключателя – thorne51

0

Отъезд в Laravel Docs on Polymorphism, есть некоторые функции, которые вы могли бы эффективно использовать с несколько иной структурой данных как таковой:

questions 
- id 
- optionable_id 
- optionable_type 

multiple_choice_options 
- id 

drag_and_drop_options 
- id 

Модели:

class Question extends Model { 
    public function optionable() { 
     return $this->morphTo(); 
    } 
} 

class MultipleChoiceOption extends Model { 
    public function question() { 
     return $this->morphMany('App\Question', 'optionable'); 
    } 
} 

class DragAndDropOptions extends Model { 
    public function question() { 
     return $this->morphMany('App\Question', 'optionable'); 
    } 
} 

записки, optionable_type столбец будет содержать класс имя модели-владельца.


Боковое примечание: логика отношений структуры данных кажется мне немного странной, но все равно может служить тому, что вы пытаетесь сделать. Вероятно, у меня были бы модели Question, Option, QuestionType, чтобы опции не зависели от вопросов и вопросов. Это позволит вам изменить тип вопроса без необходимости изменять параметры.

+0

Извините, но проблема с этим в том, что вопрос имеет много вариантов, а не наоборот. Параметры не будут повторно использоваться во всех вопросах – thorne51

0

Учитывая то, что вы пытаетесь достичь:

а) Опцион может принадлежать только к одному вопросу,

б) вопрос может иметь много вариантов,

Я думаю, что более чистое решение может включать в себя настройку структуры базы данных,

questions 
- id 
- body 
- question_type_id 

question_type 
- id 
- name 

options 
- id 
- name 
- question_id 



class question extends Model { 
    public function options() { 
     $this->hasMany('App\option','question_id') 
    } 
} 

class option extends Model { 
    public function question() { 
    return $this->belongsTo('App\question'); 
    } 
} 

ваш question_type таблица будет содержать muiltiple_choice, перетаскивание и т.д. поэтому Wou Вам не нужно использовать инструкцию «if» или «переключатель», что делает ваш код более чистым. вам также не нужно редактировать свой код всякий раз, когда вы добавляете новый тип вопроса.

Смежные вопросы