reedware / laravel-composite-relations
添加了定义复合Eloquent关系的功能。
v4.0.0
2024-03-22 20:51 UTC
Requires
- php: ^8.1
- illuminate/database: ^10.48|^11.0
- illuminate/support: ^10.48|^11.0
Requires (Dev)
- laravel/pint: ^1.5
- mockery/mockery: ^1.6.6
- php-coveralls/php-coveralls: ^2.4
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.5
- reedware/laravel-relation-joins: ^6.0
- symfony/var-dumper: ^6.4.4|^7.0
README
此包添加了在关系中有多个外键的能力。
简介
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" = ?))