All Projects → spatie → Laravel Schemaless Attributes

spatie / Laravel Schemaless Attributes

Licence: mit
Add schemaless attributes to Eloquent models

Projects that are alternatives of or similar to Laravel Schemaless Attributes

Sleekdb
Pure PHP NoSQL database with no dependency. Flat file, JSON based document database.
Stars: ✭ 450 (-24.37%)
Mutual labels:  json, nosql
Laravel Cascade Soft Deletes
Cascading deletes for Eloquent models that implement soft deletes
Stars: ✭ 498 (-16.3%)
Mutual labels:  eloquent, laravel
Laravel Medialibrary
Associate files with Eloquent models
Stars: ✭ 4,743 (+697.14%)
Mutual labels:  eloquent, laravel
Lada Cache
A Redis based, fully automated and scalable database cache layer for Laravel
Stars: ✭ 424 (-28.74%)
Mutual labels:  eloquent, laravel
Compoships
Multi-columns relationships for Laravel's Eloquent ORM
Stars: ✭ 537 (-9.75%)
Mutual labels:  eloquent, laravel
Tinydb
TinyDB is a lightweight document oriented database optimized for your happiness :)
Stars: ✭ 4,713 (+692.1%)
Mutual labels:  json, nosql
Squire
A library of static Eloquent models for common fixture data.
Stars: ✭ 496 (-16.64%)
Mutual labels:  eloquent, laravel
Laravel Eloquent Uuid
A simple drop-in solution for providing UUID support for the IDs of your Eloquent models.
Stars: ✭ 388 (-34.79%)
Mutual labels:  eloquent, laravel
Laracsv
A Laravel package to easily generate CSV files from Eloquent model
Stars: ✭ 583 (-2.02%)
Mutual labels:  eloquent, laravel
Laravel Eloquent Query Cache
Adding cache on your Laravel Eloquent queries' results is now a breeze.
Stars: ✭ 529 (-11.09%)
Mutual labels:  eloquent, laravel
Laravel Wallet
Easy work with virtual wallet
Stars: ✭ 401 (-32.61%)
Mutual labels:  eloquent, laravel
Laravel Model States
State support for models
Stars: ✭ 559 (-6.05%)
Mutual labels:  eloquent, laravel
Stream Parser
⚡ PHP7 / Laravel Multi-format Streaming Parser
Stars: ✭ 391 (-34.29%)
Mutual labels:  json, laravel
Laravel Api Response Builder
Builds nice, normalized and easy to consume Laravel REST API JSON responses.
Stars: ✭ 433 (-27.23%)
Mutual labels:  json, laravel
Laravel Model Cleanup
Clean up unneeded records
Stars: ✭ 388 (-34.79%)
Mutual labels:  eloquent, laravel
Laravel Moderation
A simple Content Moderation System for Laravel 5.* that allows you to Approve or Reject resources like posts, comments, users, etc.
Stars: ✭ 487 (-18.15%)
Mutual labels:  eloquent, laravel
Elasticsearch
The missing elasticsearch ORM for Laravel, Lumen and Native php applications
Stars: ✭ 375 (-36.97%)
Mutual labels:  eloquent, laravel
Polr
🚡 A modern, powerful, and robust URL shortener
Stars: ✭ 4,147 (+596.97%)
Mutual labels:  json, laravel
Laravel Model Status
Easily add statuses to your models
Stars: ✭ 510 (-14.29%)
Mutual labels:  eloquent, laravel
Laravel Mediable
Laravel-Mediable is a package for easily uploading and attaching media files to models with Laravel 5.
Stars: ✭ 541 (-9.08%)
Mutual labels:  eloquent, laravel

Add schemaless attributes to Eloquent models

Latest Version on Packagist GitHub Workflow Status Total Downloads

Wouldn't it be cool if you could have a bit of the spirit of NoSQL available in Eloquent? This package does just that. It provides a trait that when applied on a model, allows you to store arbitrary values in a single JSON column.

Here are a few examples. We're using the extra_attributes column here, but you can name it whatever you want.

// add and retrieve an attribute
$yourModel->extra_attributes->name = 'value';
$yourModel->extra_attributes->name; // returns 'value'

// you can also use the array approach
$yourModel->extra_attributes['name'] = 'value';
$yourModel->extra_attributes['name'] // returns 'value'

// setting multiple values in one go
$yourModel->extra_attributes = [
   'rey' => ['side' => 'light'],
   'snoke' => ['side' => 'dark']
];

// setting/updating multiple values in one go via set()
$yourModel->extra_attributes->set([
   'han' => ['side' => 'light'],
   'snoke' => ['side' => 'dark']
]);

// retrieving values using dot notation
$yourModel->extra_attributes->get('rey.side'); // returns 'light'

// retrieve default value when attribute is not exists
$yourModel->extra_attributes->get('non_existing', 'default'); // returns 'default'

// it has a scope to retrieve all models with the given schemaless attributes
$yourModel->withSchemalessAttributes(['name' => 'value', 'name2' => 'value2'])->get();

// delete key & value
$yourModel->extra_attributes->forget('key');

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Requirements

This package requires a database with support for json columns like MySQL 5.7 or higher.

Installation

You can install the package via composer:

composer require spatie/laravel-schemaless-attributes

The schemaless attributes will be stored in a json column on the table of your model. Let's add that column and prepare the model.

Adding the column where the schemaless attributes will be stored

Add a migration for all models where you want to add schemaless attributes to. You should use schemalessAttributes method on Blueprint to add a column. The argument you give to schemalessAttributes is the column name that will be added. You can use any name you'd like. You're also free to add as many schemaless attribute columns to your table as you want. In all examples of this readme we'll use a single column named extra_attributes.

Schema::table('your_models', function (Blueprint $table) {
    $table->schemalessAttributes('extra_attributes');
});

Preparing the model

In order to work with the schemaless attributes you'll need to add a cast, an accessor and a scopes on your model. Here's an example of what you need to add if you've chosen extra_attributes as your column name.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Spatie\SchemalessAttributes\SchemalessAttributes;

class TestModel extends Model
{
    // ...

    public $casts = [
        'extra_attributes' => 'array',
    ];

    public function getExtraAttributesAttribute(): SchemalessAttributes
    {
        return SchemalessAttributes::createForModel($this, 'extra_attributes');
    }

    public function scopeWithExtraAttributes(): Builder
    {
        return SchemalessAttributes::scopeWithSchemalessAttributes('extra_attributes');
    }

    // ...
}

If you need support for multiple schemaless columns on a single model, you should use SchemalessAttributesTrait trait. Here's an example of what you need to add if you've chosen extra_attributes, other_extra_attributes as your column names.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Spatie\SchemalessAttributes\SchemalessAttributes;
use Spatie\SchemalessAttributes\SchemalessAttributesTrait;

class TestModel extends Model
{
    use SchemalessAttributesTrait;

    // ...
    
    /**
     * @var array
     */
    protected $schemalessAttributes = [
        'extra_attributes',
        'other_extra_attributes',
    ];

    public function scopeWithExtraAttributes(): Builder
    {
        return SchemalessAttributes::scopeWithSchemalessAttributes('extra_attributes');
    }
    
    public function scopeWithOtherExtraAttributes(): Builder
    {
        return SchemalessAttributes::scopeWithSchemalessAttributes('other_extra_attributes');
    }

    // ...
}

If you want to reuse this behaviour across multiple models you could opt to put the function in a trait of your own. Here's what that trait could look like:

namespace App\Models\Concerns;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Spatie\SchemalessAttributes\SchemalessAttributes;

trait HasSchemalessAttributes
{
    public function getExtraAttributesAttribute(): SchemalessAttributes
    {
       return SchemalessAttributes::createForModel($this, 'extra_attributes');
    }

    public function scopeWithExtraAttributes(): Builder
    {
        return SchemalessAttributes::scopeWithSchemalessAttributes('extra_attributes');
    }
}

Usage

Getting and setting schemaless attributes

This is the easiest way to get and set schemaless attributes:

$yourModel->extra_attributes->name = 'value';

$yourModel->extra_attributes->name; // Returns 'value'

Alternatively you can use an array approach:

$yourModel->extra_attributes['name'] = 'value';

$yourModel->extra_attributes['name']; // Returns 'value'

You can replace all existing schemaless attributes by assigning an array to it.

// All existing schemaless attributes will be replaced
$yourModel->extra_attributes = ['name' => 'value'];
$yourModel->extra_attributes->all(); // Returns ['name' => 'value']

You can also opt to use get and set. The methods have support for dot notation.

$yourModel->extra_attributes = [
   'rey' => ['side' => 'light'],
   'snoke' => ['side' => 'dark'],
];
$yourModel->extra_attributes->set('rey.side', 'dark');

$yourModel->extra_attributes->get('rey.side'); // Returns 'dark

You can also pass a default value to the get method.

$yourModel->extra_attributes->get('non_existing', 'default'); // Returns 'default'

Persisting schemaless attributes

To persist schemaless attributes you should, just like you do for normal attributes, call save() on the model.

$yourModel->save(); // Persists both normal and schemaless attributes

Retrieving models with specific schemaless attributes

Here's how you can use the provided scope.

// Returns all models that have all the given schemaless attributes
$yourModel->withExtraAttributes(['name' => 'value', 'name2' => 'value2'])->get();

If you only want to search on a single custom attribute, you can use the scope like this

// returns all models that have a schemaless attribute `name` set to `value`
$yourModel->withExtraAttributes('name', 'value')->get();

Testing

First create a MySQL database named laravel_schemaless_attributes. After that you can run the tests with:

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].