我正在使用 Laravel v9.19 和 PHP 8.0 开发一个项目。
这是该项目数据库中与问题相关的部分:
这是一个 User 类:
class User extends Authenticatable
{
// ...
/**
* Get orders of this user.
*
* @return Illuminate\Database\Eloquent\Relations\HasMany
*/
public function orders(): HasMany
{
return $this->hasMany(Order::class, 'client_id');
}
}
这是一个 Order 类:
class Order extends Model
{
// ...
/**
* Get the client of this order.
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function client(): BelongsTo
{
return $this->belongsTo(User::class, 'client_id');
}
/**
* Get the ordered item.
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function item(): BelongsTo
{
return $this->belongsTo(Item::class, 'item_id');
}
}
这是一个 Item 类:
class Downloadable extends Model
{
// ...
/**
* Get the orders having this item.
*
* @return Illuminate\Database\Eloquent\Relations\HasMany
*/
public function orders(): HasMany
{
return $this->hasMany(Order::class, 'item_id');
}
}
我想利用雄辩的关系以便能够:
我需要向 User 模型添加一个新方法:
/**
* Get items ordered by this user.
*
* @return ???
*/
public function items()
{
// What to do here?
}
我需要向 Item 模型添加一个新方法:
/**
* Get users that ordered this item.
*
* @return ???
*/
public function users()
{
// What to do here?
}
由于默认的 HasManyThrough 关系需要不同的表结构,并且我无法修改现有的表结构,因此这里不适用。
作为可能的解决方案之一,我正在考虑使用 staudenmeir/eloquent-has-many-deep,创建一个名为
order_item
的新中间表来将订单映射到项目,并使用以下代码,例如项目方法:
/**
* Get items ordered by this user.
*
* @return ???
*/
public function items()
{
return $this->hasManyDeep(
Item::class,
[Order::class, 'order_item']
);
}
如果存在无需外部库的 Laravel 解决方案,或者您知道更有效的方法,请分享给我。我很想知道这种情况下的最佳实践。
class User extends Authenticatable
{
// ...
/**
* Get all items ordered by the user.
*
* @return Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function items(): HasManyThrough
{
return $this->hasManyThrough(Item::class, Order::class, 'client_id', 'id', 'id', 'item_id');
}
}
class Item extends Model
{
// ...
/**
* Get all users who ordered this item.
*
* @return Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function users(): HasManyThrough
{
return $this->hasManyThrough(User::class, Order::class, 'item_id', 'id', 'id', 'client_id');
}
}
要定义 Laravel 中的 users、orders 和 items 表之间的关系,您需要使用 Eloquent ORM 的关系功能。根据典型的业务逻辑,您可以如何定义这些表之间的关系:
1。用户和订单:
一个用户可以有多个订单(一对多关系)。 订单属于单个用户。
在 Laravel 中,您将其定义为:
用户模型:
<?php
class User extends Model
{
public function orders()
{
return $this->hasMany(Order::class);
}
}
订购型号:
<?php
class Order extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
2。订单和商品:
一个订单可以有很多商品(多对多关系)。 一个项目可以属于多个订单。
为此,您需要一个数据透视表(通常称为 order_item)来保存订单和商品之间的关系。
数据透视表迁移:
<?php
Schema::create('order_item', function (Blueprint $table) {
$table->id();
$table->foreignId('order_id')->constrained()->onDelete('cascade');
$table->foreignId('item_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
在 Laravel 中,您将其定义为:
订购型号:
<?php
class Order extends Model
{
public function items()
{
return $this->belongsToMany(Item::class);
}
}
商品型号:
<?php
class Item extends Model
{
public function orders()
{
return $this->belongsToMany(Order::class);
}
}
关系总结:
User -> hasMany -> Order.
Order -> belongsTo -> User.
Order -> belongsToMany -> Item.
Item -> belongsToMany -> Order.
此结构将允许用户下多个订单,每个订单可以有多个商品,每个商品都是多个订单的一部分。