Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

raveren/EloquentDataObject

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EloquentDataObject

composer require raveren/eloquent-data-object

Store PHP objects in Eloquent columns.


Your model column is now a strictly typed object!

image

Plus, all and any changes to your data classes in the future don't invalidate stored data!

Just extend EloquentDataObject (or see below):

<?php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Raveren\EloquentDataObject\EloquentDataObject;

Schema::table('my_table', function (Blueprint $table) {
    $table->json('json_data')->nullable(); // <---- Step 1/3 -------
});

class MyModel extends Model
{
    protected function casts(): array
    {
        return [
            'json_data' => MyData::class //  <---- Step 2/3 -------
        ];
    }
}

class MyData extends EloquentDataObject //   <---- Step 3/3 -------
{
    public string $name;
    /** @var MyData[] */
    public array $children;
}
Done!

Objects are stored as JSON inside database.

In PHP however, $myModel->json_data is always an instance of MyData.

Thus, if you receive an associative-array representation, you must convert it to MyData before saving:

$myModel->json_data = MyData::from($array); // helper method comes in the box

If your data class changes or is renamed, no data is lost and you get no errors¹: if you rename a class attribute, existing data will be preserved as a Dynamic property with the old name.

¹ Newly missing columns in class definitions issue Log::error() with detailed information.

To fix drifted names, define a renamedDataObjectColumns():

class MyData extends EloquentDataObject
{
    public string $newName;
    
    public static function renamedDataObjectColumns(): array
    {
        return [
            'name'     => 'newName',
            'children' => null, // Set new name to null to drop the value from storage on saving.
        ];
    }
}

It's enough to load each model once and re-save it to fix the name inside the DB permanently, so you don't have to keep the overridden method if you do that.


Alternatively, if you cannot `extend a class:

  1. Add use EloquentDataObjectTrait;
  2. Add implements Castable
  3. Annotate with #[AllowDynamicProperties] (only if you renamed class attributes)
#[AllowDynamicProperties]
class MyData implements Castable
{
    use EloquentDataObjectTrait;
    // ...
}

Acknowledgments

Hierarchical object conversion is handled by netresearch/jsonmapper (sole project dependency).

About

Best of all worlds for object storage in Eloquent.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Morty Proxy This is a proxified and sanitized view of the page, visit original site.