I have some modules in my application and these modules are managed by a model called Module
and their state is saved in database through this model.
Example Modules:
╔════╤═══════╤════════════╤══════════════╗
║ id │ title │ installed │ dependencies ║
╠════╪═══════╪════════════╪══════════════╣
║ 1 │ A │ false │ ['B'] ║
╟────┼───────┼────────────┼──────────────╢
║ 2 │ B │ false │ [] ║
╚════╧═══════╧════════════╧══════════════╝
These modules are installed by a method called install()
. When doing a clean installation, I retrieve all modules and then run $this->install()
in a foreach loop.
$modules = Module::all();
foreach ($modules as $module)
{
$module->install();
}
Before installation of each module, I first check if it is already installed and then check for dependencies of the module inside install()
method and install them in a recursive way and after installation each module I update installed
column to true
but this attribute will not change in my $modules
collection.
Imagine module A needs B first. B is installed in second level of my recursive method. When B is installed, the installed
flag will be updated in my database, but the flag will stay the same in $modules
collection and when installing B itself by traversing $modules
the installed
flag is still false
.
Module.php:
class Module extends Model
{
public function install(): void
{
// ** Maybe get last updated state here? **
// Check if already installed
if($this->installed) return;
// Install dependencies first
if($this->hasDependencies())
{
foreach ($this->dependencies as $dependency)
{
$dependency->install();
}
}
// Installation codes...
$this->update([ 'installed' => true ]);
}
One thing I have tried is getting the last state of model in my install()
method by this code:
$this = self::where('id',$this->id)->first();
but I found out that it's impossible to reassign $this
.
Any help from you is really appreciated.
You can use $this->refresh()
to get all the attributes repopulated from the database. https://laravel.com/docs/11.x/eloquent#refreshing-models.
You can also use Module::chunk(1, function($module) {})
instead, which will retrieve all the records, 1 by 1 already fresh instead of using all
and then needing to refresh each one again.