reedware/laravel-composite-relations

添加了定义复合Eloquent关系的功能。

v4.0.0 2024-03-22 20:51 UTC

This package is auto-updated.

Last update: 2024-09-22 22:19:17 UTC


README

Laravel Version Tests Lint Static Analysis Total Downloads

此包添加了在关系中有多个外键的能力。

简介

Eloquent 不原生支持在关系中使用复合键。虽然通常首选单键关系,但在某些情况下,它们不幸地成为必需,且没有很好的解决方案。此包提供了一个解决方案,您可以使用复合键,而且一切感觉都像是在使用 Eloquent。

此包允许您定义以下复合关系

  • 属于
  • 有一个
  • 有多个

所有复合关系都支持预加载和存在查询(例如,“where has”)。

目前没有打算添加对其他关系的支持,因为这些应该足够满足绝大多数用例。

安装

使用Composer

composer require reedware/laravel-composite-relations

版本控制

此包考虑到最新的Laravel版本进行维护,但支持遵循Laravel的支持策略

代码更改

此包不使用服务提供器或外观,而是使用特性。在您的基模型实例中,您需要包含以下内容

use Illuminate\Database\Eloquent\Model as Eloquent;
use Reedware\LaravelCompositeRelations\HasCompositeRelations;

abstract class Model extends Eloquent
{
    use HasCompositeRelations;
}

用法

1. 定义关系

复合属于

想象您正在定义一个 非复合 属于关系

public function myRelation()
{
    return $this->belongsTo(MyRelated::class, 'my_column_on_this_table', 'my_column_on_the_other_table');
}

由于复合关系使用多个键,您只需将键定义为数组即可

public function myCompositeRelation()
{
    return $this->compositeBelongsTo(MyRelated::class, ['my_first_key', 'my_second_key'], ['their_first_key', 'their_second_key']);
}

复合有一个

这遵循与复合属于关系相同的结构

public function myCompositeRelation()
{
    return $this->compositeHasOne(MyRelated::class, ['their_first_key', 'their_second_key'], ['my_first_key', 'my_second_key']);
}

复合有多个

模式继续

public function myCompositeRelation()
{
    return $this->compositeHasMany(MyRelated::class, ['foreign_1', 'foreign_2'], ['local_1', 'local_2']);
}

2. 省略外键和本地键

对于非复合关系,您实际上不需要提供外键和本地键,前提是您遵循一定的约定。此功能也适用于复合关系,但必须以不同的方式定义。以下是方法

class Task extends Models
{
    /**
     * The primary keys for the model.
     *
     * @var array
     */
    protected $primaryKeys = ['vendor_id', 'vendor_name'];

    public function importSummary()
    {
        return $this->compositeHasOne(TaskImportSummary::class);
    }
}

class TaskImportSummary extends Models
{
    public function task()
    {
        return $this->compositeBelongsTo(TaskImportSummary::class);
    }
}

3. 通过复合关系连接

此包与reedware/laravel-relation-joins兼容,这意味着您可以像连接其他任何内容一样通过复合关系连接

$task->joinRelation('importSummary', function($join) {
    $join->where('task_import_summaries.name', 'like', '%Relation joins are cool!%');
});

您必须单独包含reedware/laravel-relation-joins才能使其工作。

使用复合粘合剂

复合键之间的默认粘合剂是'or'。这意味着您的查询将类似于

where (("foreign_1" = ? or "foreign_2" = ?) or ("foreign_1" = ? or "foreign_2" = ?))

您可以通过传递'and'作为粘合剂参数来更改它

public function myCompositeBelongsToRelation()
{
    return $this->compositeBelongsTo(MyRelated::class, ['local_1', 'local_2'], ['foreign_1', 'foreign_2'], null, 'and');
}

public function myCompositeHasOneRelation()
{
    return $this->compositeHasOne(MyRelated::class, ['foreign_1', 'foreign_2'], ['local_1', 'local_2'], 'and');
}

public function myCompositeHasManyRelation()
{
    return $this->compositeHasMany(MyRelated::class, ['foreign_1', 'foreign_2'], ['local_1', 'local_2'], 'and');
}

得到以下结果

where (("foreign_1" = ? and "foreign_2" = ?) or ("foreign_1" = ? and "foreign_2" = ?))