Traditional relational databases have structure, so we use migrations to manage that structure in Laravel.
This is cool, until you find yourself creating tables for things that you don't need tables for, because none of the tables' columns act as foreign keys to keys on other tables.
E.g. a user_settings table would have a structure like
id | user_id | key | value |
---|---|---|---|
1 | 2 | bg_color | red |
2 | 3 | bg_color | blue |
Now, if you wanted to store more complicated information like what ring-tone to play when a particular user calls, you'd have to either extend the user_settings
with a migration to have a column like target_user_id
, or have a nested key like <target-user-id>/ringtone
.
Either choice would present some challenge, grouping settings to resolve during presentation.
These represent two Eloquent models that map to tables with schema:
name | type | description |
---|---|---|
id | int | Incremental ID |
model | varchar | A reference to class name of the Eloquent Model that owns this |
name | varchar | A lower-case name of the content-type e.g. bg_color |
display_name | varchar | A more user-friendly name, in case you need to display |
format | varchar | One of string , number , boolean , datetime , object or array |
related_to | int | A reference to another ContentType id that this is a child of |
created_at | timestamp | When this was created |
updated_at | timestamp | When last this was updated |
name | type | description |
---|---|---|
id | int | Incremental ID |
model_id | int | A reference to the id of the model instance that owns this content |
content_type_id | int | A reference to the content-type that this content belongs to |
value | varchar | The actual value of this content |
created_at | timestamp | When this was created |
updated_at | timestamp | When last this was updated |
- Only a content-type with an
array
format is allowed to have multiple contents. - Only a content-type with an
object
format is allowed to have child content-type(s). - A child content-type is one with its
related_to
value set to the id of another content-type. - For content-type(s) with primitive format values, the values of their content must match with their formats. E.g. a content-type with
number
format, can only have a content with a number value such as100
or0.2345
.
- When retrieving contents, the response can extend an existing model with
$builder->with('contents.type')
. Here's an example of content for adepartment
model:
{
"id": 1,
"name": "Physics",
"hod_id": 1,
"faculty_id": 1,
"created_at": "2018-08-01 08:23:36",
"updated_at": "2018-08-01 08:23:36",
"contents": [
{
"id": 1,
"owner_id": 1,
"content_type_id": 1,
"value": "array-value-1",
"created_at": "2018-08-01 08:23:36",
"updated_at": "2018-08-01 08:23:36",
"type": {
"id": 1,
"school_id": 1,
"type": "App\\Models\\Department",
"name": "type-1",
"display_name": "Type 1",
"format": "array",
"related_to": null,
"created_at": "2018-08-01 08:23:36",
"updated_at": "2018-08-01 08:23:36"
}
}
]
}
- The response can be transformed to become nested, and include only important details.
{
"id": 1,
"name": "Physics",
"hod_id": 1,
"faculty_id": 1,
"created_at": "2018-08-01 08:23:36",
"updated_at": "2018-08-01 08:23:36",
"content": {
"type-1": [
"array-value-1",
"array-value-2",
"array-value-3"
],
"type-9": "Value 1",
"type-6": {
"type-4": "object-value-1",
"type-8": 123
}
}
}