Skip to content

Config Magic

Cristian Llanos edited this page Mar 26, 2021 · 3 revisions

The config file has been designed with some magic on mind. I'll try to describe how it works...

There are some keys which provide a configuration inheritance (it's a way to describe it). The more specific the key, the more its priority. Another way to see it is the more specific key, overrides the more general ones.

$priorityKeys = [
    "@connections.{$blueprint->connection()}.{$blueprint->table()}.$key",
    "@connections.{$blueprint->connection()}.{$blueprint->schema()}.$key",
    "@connections.{$blueprint->connection()}.$key",
    "{$blueprint->qualifiedTable()}.$key",
    "{$blueprint->schema()}.$key",
    "*.$key",
];

All models inherit configurations from *.{key}. But there are certain tables which may need certain rules that do not apply to the other tables.

Let's say we have the following tables:

Schema: identity
users
- id (int)
- name
- deleted_at (datetime)
Schema: blog
posts
- id (int)
- user_id (int)
- content (string)

Let's assume we have more tables in our schemas and for most of them we use soft deletes. Our config file should probably look like this:

<?php

return [

    '*' => [
        'path' => app_path('Models'),
        'namespace' => 'App\Models',
        'soft_deletes' => true,
    ],
];

However, our posts table does not support soft deletes. Let's instruct our config file to account for that. The easiest way would be giving the table name it's own configuration space to override the only key that matters to us:

<?php

return [

    '*' => [ // Default configurations for all models
        'path' => app_path('Models'),
        'namespace' => 'App\Models',
        'soft_deletes' => true,
    ],

    'posts' => [
        'soft_deletes' => false, // Overrides default configuration for soft deletes only
    ],

];

By doing this, whenever a table with name posts is being analysed, soft deletes will be turned off for its model. The model path and its namespace would still be the ones from the * configuration.

And this is the way our config magic works.

Let's say, for some reason we need to create another posts table inside another schema such as forum

Schema: forum
posts
- id (int)
- user_id (int)
- question (string)
- deleted_at (datetime)

We now have two tables with the same name. Though, they are under different schemas. The problem is that we want to enable to the forum.posts, not to the blog.posts. To accomplish that we can do this:

<?php

return [

    '*' => [
        'path' => app_path('Models'),
        'namespace' => 'App\Models',
        'soft_deletes' => true,
    ],

    'blog' => [ // Schema
        'posts' => [ // Table
            'soft_deletes' => false, // Override
        ],
    ],

    'forum' => [
        'posts' => [
            'soft_deletes' => true, // It's the same value as the default configuration. It's here for demonstration purposes
        ],
    ],

];

In this case, the schema is the leading key and the configurations will take this more specific key to apply the rules.

I hope this brings some light into how the config file works. In addition, we can also nest configurations based con Laravel Database Connections; all we need to do is use the @connections key the same way we did with schemas.

To learn more about this feature, we can read the code ;)

Clone this wiki locally