I have a Todo
and this Todo
can have a SubTodo
. Each SubTodo
can be of the following types:
- text
- dropdown
- boolean
Each of these SubTodo
have specifics that is related to each one of its type so I resolved to separated into its own table. The database table structure is as follow:
todo
- id
sub_todo
- id
- todo_id
- type [dropdown, text, boolean]
sub_todo_dropdown
- id
- sub_todo_id
sub_todo_text
- id
- sub_todo_id
sub_todo_boolean
- id
- sub_todo_id
A SubTodo
needs to have a relationship called meta
that will resolve the fields that is specific to which type. I have defined the following relationship:
Models/SubTodo.php
// The SubTodo will have meta information on other tables
// that will be depending on the type of the SubTodo.
// To fetch those meta information's we will
// have this set where will map the
// relationship to its model
const META_MODELS = [
self::SUB_TODO_TYPE_TEXT => SubTodoText::class,
self::SUB_TODO_TYPE_BOOLEAN => SubTodoBoolean::class,
self::SUB_TODO_TYPE_DROPDOWN => SubTodoDropdown::class,
];
public function meta(): HasOne
{
return $this->hasOne(self::META_MODELS[$this->type], 'sub_todo_id');
}
But when I try to load this relationship with
$subTodos = SubTodo::with('meta')->paginate();
I get "message": "Undefined index: "
. After doing
public function meta(): HasOne
{
dd($this->type);
return $this->hasOne(self::META_MODELS[$this->type], 'sub_todo_id');
}
I get null
. My best guess is that the model wasn't loaded yet so I need to load the model first and then call meta
:
$subTodos = SubTodo::limit(10)->get()->each(function (SubTodo $subtodo) {
$subtodo->load('meta');
});
But this approach will cause a N+1
problem. Is there any way I can achieve to load meta
without having to load all models first? Is this a good usage for one to one polymorphic relationship?