denismitr / laravel-json-attributes
Laravel Json Attributes for Eloquent Models
Requires
- php: >=7.2
- illuminate/database: ~5.7.0|~5.8.0
- illuminate/support: ~5.7.0|~5.8.0
Requires (Dev)
- larapack/dd: ^1.1
- orchestra/testbench: ~3.7.0|~3.8.0
- phpunit/phpunit: ^7.3
This package is auto-updated.
Last update: 2024-12-21 21:25:58 UTC
README
Author
Denis Mitrofanov
thecollection.ru
Requirements
PHP 7.2 or higher MYSQL 5.7 or higher or POSTGRES (the one I tested it on is 9.6) probably any 9.* version or higher will do
Installation
composer require denismitr/laravel-json-attributes
In Laravel 5.5 the service provider will automatically get registered.
In older versions of the framework just add the service provider in config/app.php
file:
'providers' => [
// ...
Denismitr\JsonAttributes\JsonAttributesServiceProvider::class,
];
Usage
- First add a
jsonData
column to your table
Schema::create('orders', function (Blueprint $table) { $table->increments('id'); $table->string('description'); $table->jsonData('json_data'); });
Underneath $table->jsonData('json_data');
is just $table->json('json_data')->nullable()
.
Examples of usage:
$array = [ 'supplier' => 'Boeing', 'total_cost' => 245.99, ]; $record = Record::create(['json_data' => $array]); $this->assertEquals($array, $record->json_data->all()); $this->assertEquals('Boeing', $record->json_data->supplier); $this->assertEquals('Boeing', $record->json_data['supplier']);
Another examples with Laravel dot notation
$this->record->json_data->member = ['name' => 'John', 'age' => 30]; $this->record->json_data->forget('member.age'); $this->assertEquals($this->record->json_data->member, ['name' => 'John']);
$this->record->json_data->set('settings.connection', 'mysql'); $this->record->json_data->set('colors.navbar', 'dark'); $this->assertEquals('mysql', $this->record->json_data->get('settings.connection')); $this->assertEquals('dark', $this->record->json_data->get('colors.navbar'));
You can assign a whole array
$array = [ 'one' => 'value', 'two' => 'another value', ]; $this->record->json_data->array = $array; $this->assertEquals($array, $this->record->json_data->array);
Searching
Since version 1.0
nested search is available
$recordA = Record::create(['json_data' => [ 'company' => 'Ecommelite', 'user' => [ 'name' => 'Denis', 'job_title' => 'developer' ] ]]); $recordB = Record::create(['json_data' => [ 'company' => 'Ecommelite', 'user' => [ 'name' => 'Tom', 'job_title' => 'developer' ] ]]); $recordC = Record::create(['json_data' => [ 'company' => 'Ecommelite', 'address' => [ 'street' => '1st Street', 'phone' => 1234556 ] ]]); $this->assertContainsModels( [$recordA], Record::withJsonData(['user.name' => 'Denis'])->get() ); $this->assertContainsModels( [$recordA, $recordB], Record::withJsonData(['user.job_title' => 'developer'])->get() ); $this->assertContainsModels( [$recordA, $recordB], Record::withJsonData(['user.job_title' => 'developer', 'company' => 'Ecommelite'])->get() ); $this->assertContainsModels( [$recordA], Record::withJsonData([ 'user.job_title' => 'developer', 'company' => 'Ecommelite', 'user.name' => 'Denis' ])->get() ); $this->assertContainsModels( [$recordA, $recordB], Record::withJsonData('user.job_title', 'developer')->get() ); $this->assertContainsModels( [], Record::withJsonData(['non.existent' => 'record'])->get() );
To see more look at the tests.
Eloquent Model
First of all you need to cast the json attributes to array
Here is how the Record
model from test suite looks like:
use Denismitr\JsonAttributes\JsonAttributes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class Record extends Model { protected $casts = ['json_data' => 'array']; /** * @return JsonAttributes */ public function getJsonDataAttribute(): JsonAttributes { return JsonAttributes::create($this, 'json_data'); } /** * @return Builder */ public function scopeWithJsonData(): Builder { return JsonAttributes::scopeWithJsonAttributes('json_data'); } }
Persistence works regularly just like with any other Eloquent model