spatie / laravel-schemaless-attributes
为 Eloquent 模型添加无模式属性
Requires
- php: ^8.0
- illuminate/contracts: ^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/database: ^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^7.0|^8.0|^9.0|^10.0|^11.0
- spatie/laravel-package-tools: ^1.4.3
Requires (Dev)
- brianium/paratest: ^6.2|^7.4
- mockery/mockery: ^1.4
- nunomaduro/collision: ^5.3|^6.0|^8.0
- orchestra/testbench: ^6.15|^7.0|^8.0|^9.0
- pestphp/pest-plugin-laravel: ^1.3|^2.1
- phpunit/phpunit: ^9.6|^10.5
README
你是否想在你的 Eloquent 中加入一些 NoSQL 的精神?这个包正是这样做的。它提供了一个特质,当应用于模型时,允许你在单个 JSON 列中存储任意值。
以下是一些示例。我们在这里使用的是 extra_attributes
列,但你可以将其命名为 你想要的任何名称。
// 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 modelScope to retrieve all models with the given schemaless attributes $yourModel->withSchemalessAttributes(['name' => 'value', 'name2' => 'value2'])->get(); // delete key & value $yourModel->extra_attributes->forget('key');
支持我们
我们投入了大量资源来创建 一流的开源包。你可以通过 购买我们的付费产品之一 来支持我们。
我们非常感激你从家乡寄给我们明信片,提到你正在使用我们哪个包。你可以在 我们的联系页面 上找到我们的地址。我们将在 我们的虚拟明信片墙上 发布所有收到的明信片。
要求
此包需要一个支持 json
列的数据库,例如 MySQL 5.7 或更高版本。
安装
对于 Laravel 版本 6 & 7 或 PHP 7,请使用此包的 1.x 版本。
您可以通过 composer 安装此包
composer require spatie/laravel-schemaless-attributes
无模式属性将存储在您模型的表中的 json 列上。让我们添加该列并准备模型。
添加存储无模式属性的列
为所有你想添加无模式属性的模型添加迁移。你应该在 Blueprint
上使用 schemalessAttributes
方法来添加一个列。你给 schemalessAttributes
的参数是将要添加的列名。你可以使用你喜欢的任何名称。你也可以自由地向你的表添加任意数量的无模式属性列。在这个 README 的所有示例中,我们将使用一个名为 extra_attributes
的单列。
Schema::table('your_models', function (Blueprint $table) { $table->schemalessAttributes('extra_attributes'); });
准备模型
为了与无模式属性一起工作,你需要在你的模型上添加一个自定义转换和范围。以下是你需要添加的内容示例,如果你选择了 extra_attributes
作为你的列名。
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; class TestModel extends Model { // ... public $casts = [ 'extra_attributes' => SchemalessAttributes::class, ]; public function scopeWithExtraAttributes(): Builder { return $this->extra_attributes->modelScope(); } // ... }
如果你需要在单个模型上支持多个无模式列,你应该使用 SchemalessAttributesTrait
特质。以下是你需要添加的内容示例,如果你选择了 extra_attributes, other_extra_attributes
作为你的列名。
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 $this->extra_attributes->modelScope(); } public function scopeWithOtherExtraAttributes(): Builder { return $this->other_extra_attributes->modelScope(); } // ... }
如果你想在多个模型之间重用此行为,你可以选择将函数放入你自己的特质中。以下是一个这样的特质示例
namespace App\Models\Concerns; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; trait HasSchemalessAttributes { public function initializeHasSchemalessAttributes() { $this->casts['extra_attributes'] = SchemalessAttributes::class; } public function scopeWithExtraAttributes(): Builder { return $this->extra_attributes->modelScope(); } }
用法
获取和设置无模式属性
这是获取和设置无模式属性最简单的方式
$yourModel->extra_attributes->name = 'value'; $yourModel->extra_attributes->name; // Returns 'value'
或者,你可以使用数组方法
$yourModel->extra_attributes['name'] = 'value'; $yourModel->extra_attributes['name']; // Returns 'value'
你可以通过将数组赋值给它来替换所有现有的无模式属性。
// All existing schemaless attributes will be replaced $yourModel->extra_attributes = ['name' => 'value']; $yourModel->extra_attributes->all(); // Returns ['name' => 'value']
你也可以选择使用 get
和 set
方法。这些方法支持点表示法。
$yourModel->extra_attributes = [ 'rey' => ['side' => 'light'], 'snoke' => ['side' => 'dark'], ]; $yourModel->extra_attributes->set('rey.side', 'dark'); $yourModel->extra_attributes->get('rey.side'); // Returns 'dark
你还可以将默认值传递给 get
方法。
$yourModel->extra_attributes->get('non_existing', 'default'); // Returns 'default'
持久化无模式属性
要持久化无模式属性,就像处理普通属性一样,您应该在模型上调用 save()
方法。
$yourModel->save(); // Persists both normal and schemaless attributes
检索具有特定无模式属性的模型
以下是使用提供的 modelScope 的方法。
// Returns all models that have all the given schemaless attributes $yourModel->withExtraAttributes(['name' => 'value', 'name2' => 'value2'])->get();
如果您只想搜索单个自定义属性,可以使用 modelScope 如下所示
// returns all models that have a schemaless attribute `name` set to `value` $yourModel->withExtraAttributes('name', 'value')->get();
此外,如果您只想搜索具有自定义运算符的单个自定义属性,可以使用 modelScope 如下所示
// returns all models that have a schemaless attribute `name` starting with `value` $yourModel->withExtraAttributes('name', 'LIKE', 'value%')->get();
如果您只想搜索嵌套自定义属性,可以使用 modelScope 如下所示
// returns all models that have a schemaless nested attribute `han.side` set to `light` $yourModel->withExtraAttributes('han->side', 'light')->get();
测试
首先创建一个名为 laravel_schemaless_attributes
的 MySQL 数据库。然后您可以运行测试:
composer test
变更日志
有关最近更改的更多信息,请参阅 变更日志。
贡献
有关详细信息,请参阅 贡献指南。
安全漏洞
有关如何报告安全漏洞,请参阅 我们的安全策略。
鸣谢
许可协议
MIT 许可协议 (MIT)。有关更多信息,请参阅 许可文件。