worksome/model-attributes

此包已被废弃,不再维护。未建议替代包。

模型属性是添加为关系模型上的动态生成数据。

v0.2.0 2023-02-01 12:18 UTC

This package is auto-updated.

Last update: 2023-03-29 12:36:11 UTC


README

run-tests PHPStan

模型属性是模型的动态生成值。它们用作优雅的关系,可以预加载。

安装

您可以通过 composer 安装此包

composer require worksome/model-attributes

用法

假设我们有以下表结构

users:
- id

reviews:
- id
- user_id
- stars

以下模型

class User extends Model 
{
    public function reviews()
    {
        $this->hasMany(Review::class);
    }
}
class Review extends Model 
{
    public function user()
    {
        $this->belongsTo(User::class);
    }
}

我们可以为每个用户添加一个 rating 属性,它是用户评价的平均值。首先,我们将创建一个模型属性

class Rating extends \Worksome\ModelAttributes\ModelAttribute
{
    protected $casts = [
        'id' => 'int',
        'user_id' => 'int',
        'rating' => 'float',
    ];

    public static function attributeGlobalScope(Builder $query): void
    {
        $ratingModel = new Rating();

        $query
            ->groupBy($ratingModel->user()->getForeignKeyName())
            ->addSelect([
                $ratingModel->getKeyName(), // id
                $ratingModel->user()->getForeignKeyName(), // user_id
                \DB::raw('avg(stars) as rating'), // rating
            ]);
    }
}

并将其作为关系添加到用户模型中

public function rating(): \Worksome\ModelAttributes\AttributeRelation|\Illuminate\Database\Eloquent\Relations\HasOne
{
    return new \Worksome\ModelAttributes\AttributeRelation(
        $this->hasOne(Rating::class)
    );
}

这样就可以像这样使用它

$user = User::first();
$rating = $user->rating; // The rating model attribute created above
$rating->rating // the actual rating

由于模型属性本质上是在动态生成数据,而评分是一个标量,因此我们可以覆盖模型中的 getValue() 方法,以“更快地”获取评分

public function getValue()
{
    return $this->rating;
}

现在可以这样访问评分

User::first()->rating;

因为它是一个关系,它可以预加载

User::with('rating')->get()->map->rating;

测试

composer test

变更日志

请参阅 CHANGELOG 了解最近更改的更多信息。

致谢

许可

MIT 许可证 (MIT)。请参阅 许可文件 了解更多信息。