andy-shi88 / laravel-eloquent-flags
working with flags field on laravel eloquent integer field
0.0.1
2025-03-22 05:51 UTC
Requires
- php: >=8.0
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- laravel/pint: 1.8.0
- orchestra/testbench: ^7.0|^8.0|^9.0|^10.0
- pestphp/pest: ^1.20|^2.0|^3.0
README
This package contains a trait HasFlags to make Eloquent models able to handle multiple flag values using just integer column type. The column type can be any unsigned number type.
Install
composer require andy-shi88/laravel-eloquent-flags
Limitation
The number of flags per column this can handle depends on its datatype.
- unsignedInteger(): 32 flags
- unsignedBigInteger(): 64 flags
Usages
Setup Models
- With the schema like this.
Schema::create('person', function (Blueprint $table) { $table->id(); $table->string('name'); $table->unsignedInteger('category')->nullable(); // can handle nullable field $table->unsignedInteger('ownership')->default(0); $table->timestamps(); });
- Implement
Flagable
interface, useHasFlags
trait, and set$flagableColumns
to column that want to be used as integer flags.$flagableColumn
is formatted as:[ 'column_1': [...$labels], 'column_2': [...$labels], ]
use AndyShi88\LaravelEloquentFlags\HasFlags; use AndyShi88\LaravelEloquentFlags\Interfaces\Flagable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Person extends Model implements Flagable { use HasFactory; use HasFlags; public $table = 'person'; public $flagableColumns = [ 'ownership' => ['car', 'bike', 'house', 'computer', 'phone', 'console'], 'category' => ['asian', 'white', 'black', 'hispanic', 'middle-eastern'], ]; /** * The attributes that are mass assignable. * * @var list<string> */ protected $fillable = [ 'name', 'ownership', 'category', ]; }
Query Usages
- Store data, this will save the
ownership
andcategory
field asinteger
in the database, but readable as array of labels we specified.
$a = Person::factory()->create([ 'name' => 'a', 'ownership' => ['car', 'house', 'phone'], 'category' => ['asian', 'white'], ]); $b = Person::factory()->create([ 'name' => 'b', 'ownership' => ['car', 'bike', 'house', 'computer', 'phone', 'console'], 'category' => ['white', 'hispanic'], ]); $c = Person::factory()->create([ 'name' => 'c', 'ownership' => ['car', 'bike'], 'category' => ['asian', 'middle-eastern'], ]); $d = Person::factory()->create([ 'name' => 'd', 'ownership' => ['computer', 'phone', 'console'], 'category' => ['asian', 'middle-eastern'], ]);
$resSome = Person::whereSome([ 'column' => 'ownership', 'values' => ['car', 'bike'] ])->get(); // return $b, $c
$resAll = Person::whereAll([ 'column' => 'ownership', 'values' => ['car', 'house', 'phone'] ])->get(); // return $a
$resIntersect = Person::whereIntersect([ 'column' => 'ownership', 'values' => ['car', 'house', 'phone'] ])->get(); // return $a, $b, $c, $d // specifying number of minimal intersected value [mysql] $resIntersect = Person::whereIntersect([ 'column' => 'ownership', 'values' => ['car', 'house', 'phone'] ], 2)->get(); // return $a, $b
We'll also by default get the readable array of the fields:
$a = Person::factory()->create([ 'name' => 'a', 'ownership' => ['car', 'house', 'phone'], 'category' => ['asian', 'white'], ]); dd([ 'ownership' => $a->ownership, 'category' => $a->category ]); // we'll see /** * array:2 [ * "ownership" => array:3 [ * 0 => "car" * 1 => "house" * 2 => "phone" * ] * "category" => array:2 [ * 0 => "asian" * 1 => "white" * ] *] */