wardenyarn/model-properties

为您的 Laravel 模型添加属性

1.0.0 2021-10-07 14:52 UTC

This package is auto-updated.

Last update: 2024-09-07 21:53:35 UTC


README

简单的模型属性实现。

问题

想象一下,您有一个具有给定模式的 Page 模型

Schema::create('pages', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('slug');
    $table->text('body');
    $table->timestamps();
});

但是,您可能决定添加一个 meta_title 属性。或者一些可能只对一两个页面有用的属性。最后,我们可能会看到以下内容

Schema::create('pages', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('slug');
    $table->text('body');
    $table->boolean('has_halloween_theme');
    $table->string('meta_title');
    $table->string('meta_description');
    $table->integer('number_of_external_links');
    $table->boolean('export_to_rss');
    ...
    $table->timestamps();
});

解决方案

为了避免扩展原始表,我们可以使用一对一关系。但您需要为每个具有属性模型的模型创建一个额外的表。所以,我们可能只使用属性和模型的多态关系。

Schema::create('property_values', function (Blueprint $table) {
    $table->id();
    $table->morphs('entity');
    $table->morphs('property');
    $table->text('value')->nullable();
    $table->timestamps();
});

此包旨在简化这种多态关系设置。

安装

您可以通过 composer 安装此包

composer require wardenyarn/model-properties

用法

首先,我们需要发布属性表并迁移它。

php artisan vendor:publish --provider="Wardenyarn\Properties\PropertiesServiceProvider" --tag="migrations"

php artisan migrate

其次,我们需要添加 HasProperties 特性并填写受保护的 $properties 属性。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Wardenyarn\Properties\Models\HasProperties;

class Page extends Model
{
    use HasProperties;

    protected $properties = [
        'meta_title' => [
            'cast' => 'string',
            'default' => 'This is a page',
        ],
        'tags' => [
            'cast' => 'array',
        ],
    ];
}

最后,执行 artisan properties:fill 命令,该命令将模型 $properties 中的属性持久化到数据库中;

php artisan properties:fill

访问属性

只需使用 $model->properties 属性来访问包含所有内容的 Properties 对象。

$page = Page::first();

echo $page->properties->meta_title;

foreach ($page->properties->tags as $tag) {
	echo $tag;
}

保存

通过 $model->properties->property_name 或使用 $model->properties->set() 方法设置属性值。

$page = Page::first();

$page->properties->meta_title = 'New meta title';
$page->properties->last_admin_check = date();
// OR
$page->properties->set([
	'meta_title' => 'New meta title',
	'last_admin_check' => date(),
]);

$page->properties->save();
// OR
$page->save();

它也适用于新的模型实例

$page = new Page;
$page->name = 'New page';
$page->properties->meta_title = 'a new page';
$page->save();

注意:在这种情况下,只有 $model->save() 方法会保存属性。

类型转换

属性值将由 Laravel 自动转换。

protected $properties = [
    'last_admin_check' => [
        'cast' => 'datetime',
    ],
];

...

get_class($post->properties->last_admin_check); // Illuminate\Support\Carbon

可用的类型转换

  • array
  • boolean
  • collection
  • date
  • datetime
  • immutable_date
  • immutable_datetime
  • double
  • float
  • integer
  • real
  • string
  • timestamp

如果您需要在保存后立即访问转换后的属性,请在使用之前使用 fresh() 模型。

$page->properties->last_admin_check = date();
$page->properties->save();

gettype($page->properties->last_admin_check); // string

$page->fresh();

gettype($page->properties->last_admin_check); // object Illuminate\Support\Carbon

默认值

您可以定义属性的默认值

protected $properties = [
    'meta_title' => [
        'cast' => 'string',
        'default' => 'Page title',
    ],
];

...

$post->properties->meta_title = null;
$post->save();

echo $post->properties->meta_title; // Page title

缓存

属性值将在首次访问 properties 属性时永久缓存,因此数据库负载不会成为问题。

属性或模型保存时将刷新缓存。

$page->properties->save(); // Clears the cache
$page->save(); // Clears the cache

您始终可以使用 artisan 命令清除所有 Laravel 缓存

php artisan cache:clear

配置

您可以在导入后更改配置

php artisan vendor:publish --provider="Wardenyarn\Properties\PropertiesServiceProvider" --tag="config"

测试

composer test

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件

Laravel 包模板

此包是使用 Laravel 包模板 生成的。