fhteam/eloquent-custom-attributes

Laravel Eloquent ORM 的自定义属性处理

dev-master 2015-11-03 10:15 UTC

This package is not auto-updated.

Last update: 2024-09-28 17:38:23 UTC


README

这个小型库允许您在 Eloquent 模型上定义自定义(虚拟)属性,并使用它们与真实属性交互(或选择不交互)。

安装

  • 简单的 Composer 安装即可: composer require fhteam/eloquent-custom-attributes:dev-master (将版本要求设置为您喜欢的版本)

用法

  • CustomAttributeHelperTrait 添加到您的模型中,并将任意数量的各种属性处理特质添加到您的模型中
  • 定义 $customAttributes 属性,并在此列出属性名称以及负责处理的类
  • 覆盖 Eloquent 的 getAttributesetAttribute 方法,以便它们与您的自定义属性一起工作
  • 之后,您可以像通常一样处理属性。请参见下面的示例
/**
 * @property array $json_meta_data This attribute is actually of 'string' 
 *                                 type in database and in model. 
 *                                 But we can work with it just like 
 *                                 it is array delegating all underlying 
 *                                 operations to JsonAttrHandlerTrait
 */
class Invoice extends Eloquent
{
    use CustomAttributeHelperTrait;
    use JsonAttrHandlerTrait;

    protected $customAttributes = [
        'json_meta_data' => JsonAttrHandlerTrait::class,
    ];

    /**
     * We have to override Eloquent's getAttribute() /  
     * setAttribute() on the model directly (not in CustomAttributeHelperTrait) 
     * because you might wish to do something in those methods yourself
     */
    public function getAttribute($key)
    {
        if ($this->isCustomAttribute($key)) {
            return $this->getCustomAttribute($key);
        }

        return parent::getAttribute($key);
    }

    public function setAttribute($key, $value)
    {
        if ($this->isCustomAttribute($key)) {
            $this->setCustomAttribute($key, $value);

            return;
        }

        parent::setAttribute($key, $value);
    }
    
/**
 * Just some simple class to show actual work with model ;)
 */
class Main
{
    public function main() {
        $invoice = Invoice::findOrFail(1);
        $invoice->json_meta_data = ['key' => 'value'];
        $invoice->json_meta_data['key_next'] = 'value_next';
        
        $invoice->save();
    }
}

有趣

  • 自定义属性的名称可以与 Laravel 模型的真实属性名称相同。在这种情况下,自定义属性将隐藏真实属性,然后只能通过负责的特质与它交互(当然,您仍然可以通过 $model->attributes[] 访问原始属性值)。但当然,如果您需要它们都可见,您可以为自定义属性使用另一个名称与真实属性交互
  • 您可以使用一个自定义属性(例如,date 属性)与模型的好几个底层真实属性交互(例如,daymonthyear,如果您愿意,可以分别交互)

扩展

如果您想实现自己的自定义属性处理器,您只需实现负责值转换的特质

  • 此类特质的命名约定为 <typeName>AttrHandlerTrait
  • 属性处理特质必须实现两个方法:handleGetAttribute<typeName>handleSetAttribute<typeName>。以 Json\JsonAttrHandlerTrait 为例
  • 注意特质中的方法命名。不要使它们过于常见,因为它们必须很好地与 Eloquent 模型可能使用的其他特质的 方法共存
  • 如果您的自定义属性表示复杂类型(不仅仅是字符串或数字),请考虑创建一个包装器。此类包装器的示例可以是 ArrayAttributeWrapper。它封装数组值,提供对其的访问,并在属性更改时更新相应的模型。包装器被缓存,因此属性可以从脚本的任何部分多次访问