簡體   English   中英

Laravel中與參數的急切負載關系

[英]Eager load relationship with parameter in Laravel

在我的 Laravel 應用程序中,我希望有一個關系有條件地從兩個表之一加載數據,具體取決於指定的參數。

我有兩個具有相同列的數據透視表,稱為driver_routedriver_route_history 它們都關聯driver_idroute_id列。 唯一的區別是driver_route_history有一個date列,其中包含一個絕對的時間日期(例如 06/08/2022),而driver_route有一個weekday列,它指的是當前周。

driver_route中的記錄可由用戶修改。 在每周結束時,它們被克隆到driver_route_history ,這樣每周的變化都會被保存下來。

我希望能夠提取一天的數據。 如果指定日期在當前周內或引用未來日期,則應從driver_route加載數據。 如果日期早於本周開始,則應從driver_route_history中提取數據。

我有一個可以做到這一點的函數,當通常從應用程序內的某個地方作為函數調用時:

    public function driversOnDay($date)
    {
        $carbon_date = Carbon::parse($date);
        if ($carbon_date->isBefore(Carbon::today()->startOfWeek())) {
            return $this->belongsToMany(Driver::class, 'driver_route_history')->wherePivot('date', $carbon_date);
        } else {
            return $this->belongsToMany(Driver::class, 'driver_route')->wherePivot('weekday', strtolower($carbon_date->shortDayName));
        }
    }

我想使用 Laravel 的熱切加載在每個 Route 記錄上加載這個關系,如下所示:

Route::with(['driversOnDay' => function($query) { ... });

如何將driversOnDay date參數包含在這個急切的加載調用中?

據我了解,模型Route通過多對多關系與Driver模型相關聯,如果 $date 在本周或將來, driver_route_history需要通過driver_route數據透視表加入關系,如果$date $date ,則需要通過 driver_route_history 數據透視表加入關系早於本周開始。

一種方法是在模型上定義兩個獨立的關系,然后使用范圍:

class Route extends Model
{
    public function driversOnDay()
    {
        return $this->belongsToMany(Driver::class, 'driver_route');
    }


    public function driversOnDayHistory()
    {
        return $this->belongsToMany(Driver::class, 'driver_route_history');
    }

    public function scopeWithDrivers($query, $date)
    {
        $carbon_date = Carbon::parse($date);
        return $query
            ->when(
                $carbon_date->isBefore(Carbon::today()->startOfWeek()),
                function($query) use($carbon_date){
                    $query->with([
                        'driversOnDayHistory' => function($query) use($carbon_date){
                            $query->wherePivot('weekday', strtolower($carbon_date->shortDayName));
                        }
                    ]);
                },
                function($query) use($carbon_date){
                    $query->with([
                        'driversOnDay' => function($query) use($carbon_date){
                            $query->wherePivot('date', $carbon_date);
                        }
                    ]);
                }
            );
    }
}

然后您可以在任何地方使用Route模型上的本地范圍

$records = Route::query()->withDrivers($date)->get();

因此,如果日期在過去$records將有driversOnDayHistory急切加載,否則它將有driversOnDay急切加載。

更新

有沒有辦法重命名屬性,所以它在兩種情況下都具有相同的名稱? 現在,加載的集合根據加載的關系命名不同。

您可以操作生成的集合。 假設您總是希望將預先加載的關系作為driversOnDay提供,那么您可以嘗試

$records = Route::query()
    ->withDrivers($date)
    ->get()
    ->map(function($route) {
        if($route->relationLoaded('driversOnDayHistory')) {
            $drivers = $route->driversOnDayHistory;
            $route->unsetRelation('driversOnDayHistory');
            $route->setRelation('driversOnDay', $drivers);
        }

        return $route;
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM