我正在开发一个跟踪货物交付的项目。 我的想法是,一次送货可以到达不同的地方,而所有这些地方都是单程相连的。
这是我的雄辩式架构:
class Delivery extends Model
{
public function places()
{
return $this->hasMany(Place::CLASS, 'delivery_id');
}
public function trips()
{
// what should I do here?
}
}
class Place extends Model
{
public function delivery()
{
return $this->belongsTo(Delivery::CLASS, 'delivery_id');
}
}
class Trip extends Model
{
public function departurePlace()
{
return $this->belongsTo(Place::CLASS, 'departure_place_id');
}
public function arrivalPlace()
{
return $this->belongsTo(Place::CLASS, 'arrival_place_id');
}
}
基本上,我想做的是获得与一次送货相关的所有旅行。或者,换句话说,连接一次送货必须经过的所有地点的所有行程。 这是实现我想要的结果的SQL查询:
select distinct trip.*
from delivery
join place on (place.delivery_id = delivery.id)
join trip on (place.id = trip.arrival_place_id or place.id = trip.departure_place_id)
我希望在我的trips()
模型上有一个Delivery
方法,该方法返回该结果。
但是,我对于如何使用Eloquent实现这一目标感到困惑。
答案 0 :(得分:1)
不幸的是,我们可以简单地使用union
方法来实现此目的,但似乎不适用于hasManyThrough
关系。
无论如何,我认为Eloquent
关系并不意味着用于实现这种特定查询。
相反,您可以使用Eloquent
scopes来实现。
因此,根据@Saengdaet的答案,我们可以编写两个关系,然后将它们与scope
组合:
(顺便说一句:我不知道你为什么说他的代码出了错...)
class Delivery extends Model
{
public function places()
{
return $this->hasMany(Place::class);
}
public function outboundTrips()
{
return $this->hasManyThrough(
Trip::class,
Place::class,
"delivery_id", // Foreign key on places table
"departure_place_id", // Foreign key on trips table
);
}
public function inboundTrips()
{
return $this->hasManyThrough(
Trip::class,
Place::class,
"delivery_id", // Foreign key on places table
"arrival_place_id", // Foreign key on trips table
);
}
public function scopeTrips($query)
{
$deliveriesWithTrips = $query->with(['outboundTrips', 'inboundTrips'])->get();
$trips = [];
$deliveriesWithTrips->each(function ($elt) use (&$trips) {
$trips[] = $elt->inboundTrips->merge($elt->outboundTrips);
});
return $trips;
}
}
现在,要检索给定交付的所有行程,只需编写:
Delivery::where('id', $id)->trips();
答案 1 :(得分:0)
如果您想使用Delivery
模型来获取所有旅程,则可以使用“ hasManyThrough”关系,该关系为通过中间关系访问远处的关系提供了便捷的快捷方式。
但是您必须在Trip
模型上选择要用来关联它的FK
您可以参考"has-many-through" relationship
class Delivery extends Model
{
public function places()
{
return $this->hasMany(Place::CLASS, 'delivery_id');
}
public function trips()
{
return $this->hasManyThrough(
Trip::Class,
Place::Class,
"delivery_id", // Foreign key on places table
"departure_place_id", // Foreign key on trips table
"id", // Local key on deliveries table
"id" // Local key on places table
);
}
}