Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here
Premium Members Only
Join to unlock this tutorial and all of our courses.
Tutorial Premium Tutorial

Store Laravel Global Settings in the Database (with Caching)

May 12, 2023
8 min read

Do you store Laravel global settings in the config files? Would you want them to be editable without touching the code? Let's build a Settings page where you can change things quickly.

Database Settings

Notice: In this simple tutorial we won't use any packages for this, but at the end, I will give a few additional links for extra resources using packages.


1. Setup new Laravel project

For this tutorial, we will start with a new Laravel project with Laravel Breeze as a starter kit.

laravel new demo-database-settings
cd demo-database-settings
composer require laravel/breeze
php artisan breeze:install blade
php artisan migrate

2. DB Structure: Settings Model with Migration and Seeder

php artisan make:model Setting -mcs

Let's add the key and value columns to our migration file. We ensure that the key is always unique and that value can have a null value.

database/migrations/2023_05_12_040715_create_settings_table.php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
return new class extends Migration {
public function up(): void
{
Schema::create('settings', function (Blueprint $table) {
$table->id();
$table->string('key')->unique();
$table->string('value')->nullable();
$table->timestamps();
});
}
};

In the model, allow key and value attributes to be mass assignable by adding the $fillable property.

app/Models/Setting.php

namespace App\Models;
 
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
 
class Setting extends Model
{
use HasFactory;
 
protected $fillable = ['key', 'value'];
}

Let's add some initial entries into the seeder:

database/seeders/SettingSeeder.php

namespace Database\Seeders;
 
use App\Models\Setting;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
 
class SettingSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$settings = [
['key' => 'site_name', 'value' => 'Article about database settings'],
['key' => 'description', 'value' => 'Learn how to manage app settings using database.'],
['key' => 'admin_email', 'value' => '[email protected]'],
['key' => 'posts_per_page', 'value' => 10],
['key' => 'users_can_register', 'value' => true],
];
 
Setting::insert($settings);
}
}

Make sure you call SettingSeeder by adding it to DatabaseSeeder.

database/seeders/DatabaseSeeder.php

namespace Database\Seeders;
 
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
 
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
$this->call(SettingSeeder::class);
}
}

Finally, you can run migrations with seeders:

php artisan migrate --seed

3. Controller, Routes, and View

Our Controller will have edit() and update() methods to show form and update values:

app/Http/Controllers/SettingsController.php

namespace App\Http\Controllers;
 
use App\Models\Setting;
use Illuminate\Http\Request;
 
class SettingsController extends Controller
{
public function edit()
{
return view('settings', [
'settings' => Setting::get(['key', 'value'])
]);
}
 
public function update(Request $request)
{
$data = $request->except('_token');
 
foreach ($data as $key => $value) {
Setting::where('key', $key)->update(['value' => $value]);
}
 
return to_route('settings.edit')
->withStatus('Settings updated successfully.');
}
}

Create the settings blade view with the following...

Premium Members Only

This advanced tutorial is available exclusively to Laravel Daily Premium members.

Premium membership includes:

Access to all premium tutorials
Video and Text Courses
Private Discord Channel

Comments & Discussion

A
andywong31 ✓ Link copied!

Povilas you forgot to mention to run the below command to regenerate the autoload file after updating composer.json:

composer dump-autoload

GK
Gavin Kimpson ✓ Link copied!

Minor - but I think the SettingsSeeder should probably be singular so SettingSeeder

PK
Povilas Korop ✓ Link copied!

Good catch, fixed!

GK
Geovane Kruger ✓ Link copied!

Thanks.

This tutorial opened my mind to a customizable configuration scheme for each company.

Just add a company_id field to the settings table and use a unique for the [key,company_id] pair.

FC
Flavius Constantin ✓ Link copied!

Its the easiest solution, for sure.

RA
Richard A. Hoyle ✓ Link copied!

Grate Corus I got it to work grate then I added a user table seeder using the Uuid at first they did not work; however after removing the Uuid from the Settings table and the Model It work just fine.

K
kaleemullah ✓ Link copied!

Wonderful tip.

S
SquareNetMedia ✓ Link copied!

This is great, is there a way to split out the settings into different tabs? If I added in the sites social media links, I would like to add this to a tab in the admin settings called Social.

M
Modestas ✓ Link copied!

There is a couple of ways to do that:

  1. Create another page with the social settings. This is a simple repeating of the settings page, but only with social information. Separate controller to load the page and update the data.
  2. Use JavasScript to add "tabs" on your page. Then, you can handle it as a separate form or as a same one with different fields - that's up to you

I can't tell for sure which is best, but I don't see anything limiting this

VA
Vitaliy Artyukh ✓ Link copied!

Good job. As for me in update method the beter way will be update cache store with new data instead of forget all cache and do new db query for fetch new data

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.