Laravel 5多态关系

时间:2016-02-15 07:15:35

标签: laravel eloquent polymorphic-associations

目前还不完全清楚,因为这是我第一次修补这个问题。我的表结构如下:

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

如何设置它以使用多态关系?

3 个答案:

答案 0 :(得分:0)

您只需在options()关系中构建一个开关:

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

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

答案 1 :(得分: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列将包含拥有模型的类名。

旁注,您的数据结构关系逻辑似乎对我来说有点奇怪,但可能仍然可以满足您的要求。我可能会有模型QuestionOptionQuestionType,因此选项与问题和问题类型无关。这样您就可以更改问题类型,而无需更改选项。

答案 2 :(得分:0)

考虑你想要实现的目标:

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