Laravel 5 多态关系

Laravel 5 Polymorphic Relationship

目前还不完全清楚,因为这将是我第一次对此进行修补。我的table结构如下:

questions
- id
- type_id

multiple_choice_options
- id
- question_id

drag_and_drop_options
- id
- question_id

questions table 上的 type_id 字段决定从哪些选项 table 加载。所以基本上我想在 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);
    }
}

如何设置它以处理多态关系?

您可以简单地在 options() 关系中构建一个开关:

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

请注意这些神奇的关系,您需要在您的应用中进行额外的类型检查和仔细的编码。

查看 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 列将包含所属模型的 class 名称。


旁注,你的数据结构关系逻辑对我来说似乎有点奇怪,但可能仍然服务于你正在尝试做的事情。我可能会使用模型 QuestionOptionQuestionType,以便选项独立于问题和问题类型。这将使您能够更改问题类型而无需更改选项。

考虑到您要实现的目标:

a)一个选项只能属于一个问题,

b)一个问题可以有多个选项,

我认为更简洁的解决方案可能涉及调整您的数据库设计,

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 table 将包含 muiltiple_choice、拖放等,因此您无需使用 'if' 语句或 'switch',这让你的代码更简洁。您也不需要在添加新问题类型时编辑代码。