mistersaal/laravel-mongodb-embedded-models

比Laravel中自定义类型转换更高效、更简单的在mongodb模型中嵌入模型的方法。

1.0.2 2020-04-13 19:08 UTC

This package is auto-updated.

Last update: 2024-09-14 04:38:03 UTC


README

比Laravel中自定义类型转换更高效、更简单的在mongodb模型中嵌入模型的方法。此包是 jenssegers/mongodb 包的扩展。

在Laravel 7的新开发版本 jenssegers/mongodb develop 中移除了嵌入式关系。而不是关系,建议使用Laravel的自定义类型转换。但是当存在多层嵌入式时(例如:User),自定义类型转换对性能(了解更多)非常不好。

{
  "name": "Stepan",
  "email": "myemail@gmail.com",
  "facebookAccount": {
    "accessToken": "",
    "id": 123
  },
  "albums": [
    {
      "name": "My photos",
      "photos": [
        {
          "path": "./me.jpg",
          "description": "Just a photo"
        },
        {
          "path": "./qwerty.jpg",
          "description": "Another photo"
        }
      ]
    }
  ]
}

Laravel在每次与模型交互时都会调用cast set方法,并且每次都会将所有嵌入的模型转换为数组。我可能还会提供更多详细的测试结果,但请相信我,当对模型有大量调用时,自定义类型转换会极大地加载系统。

安装

确保您已安装 jenssegers/mongodb develop

通过Composer安装包

composer require mistersaal/laravel-mongodb-embedded-models

用法

每个包含嵌入式模型的模型都应该 实现 Mistersaal\Mongodb\Embed\HasEmbeddedModelsInterface 并使用 use Mistersaal\Mongodb\Embed\HasEmbeddedModels 特性。

每个模型都必须有 $fillable$guarded 属性以支持批量赋值。

在包含嵌入式模型的每个模型中,您应该定义 protected $embedMany = []; 或/和 protected $embedOne = [];,其中键是属性的名称,值是模型类名。

在embedOne关系中,当从数据库接收模型时,该属性将被转换成模型。在embedMany关系中,该属性将被转换成Laravel Collection的模型。当模型保存到数据库时,模型将转换为属性数组。

在包含嵌入式模型的每个模型中,您应该定义构造函数

public function __construct($attributes = []) {
    parent::__construct($attributes);
    $this->setEmbeddedAttributes();
}

要保存嵌入式模型,只需保存基本模型。所有操作都是通过基本模型进行的。

代码示例

namespace App;

use Mistersaal\Mongodb\Embed\HasEmbeddedModelsInterface;
use Mistersaal\Mongodb\Embed\HasEmbeddedModels;
use Jenssegers\Mongodb\Eloquent\Model;

class User extends Model implements HasEmbeddedModelsInterface
{
    use HasEmbeddedModels;

    protected $connection = 'mongodb';
    protected $guarded = [];

    public function __construct($attributes = []) {
        parent::__construct($attributes);
        $this->setEmbeddedAttributes();
    }

    protected $embedMany = [
        'albums' => Album::class,
    ];
    protected $embedOne = [
        'facebookAccount' => FacebookAccount::class,
    ];

}

class Album extends Model implements HasEmbeddedModelsInterface
{
    use HasEmbeddedModels;

    protected $connection = 'mongodb';
    protected $guarded = [];

    public function __construct($attributes = []) {
        parent::__construct($attributes);
        $this->setEmbeddedAttributes();
    }

    protected $embedMany = [
        'photos' => Photo::class,
    ];

}

class Photo extends Model
{

    protected $connection = 'mongodb';
    protected $guarded = [];

}

class FacebookAccount extends Model
{

    protected $connection = 'mongodb';
    protected $guarded = [];

}

如果您想重写静态 boot 方法,您应该保存其初始结构

protected static function boot()
{
    parent::boot();
    static::retrieved(function ($model) {
        $model->setEmbeddedAttributes();
    });
    static::saving(function ($model) {
        $model->setSerializedEmbeddedAttributes();
    });
}