【问题标题】:Laravel with() Eloquent as variable or another arrayLaravel with() Eloquent 作为变量或另一个数组
【发布时间】:2021-06-12 12:46:20
【问题描述】:

我有这个 Eloquent 查询想要按天、昨天、一周、上周、本月、上个月、今年、去年显示订单,这是我的代码,但是,它不起作用或确实有重新做代码的想法。在我的示例代码中,我不知道如何使用不同的参数将每个 with() 查询放入另一个查询中。请帮忙。

$product_orders = Product::where('status', 'active')
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->where('created_at', '>=', today());
    }])
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->where('created_at', '>=', Carbon::yesterday());
    }])
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->where('created_at', '>=', [now()->startOfWeek(), now()->endOfWeek()]);
    }])
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->where('created_at', '>=', [now()->subWeek()->startOfWeek(), now()->subWeek()->endOfWeek()]);
    }])
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->whereYear('created_at', '=', now()->year);
        $query->whereMonth('created_at', '=', now()->month);
    }])
    ->with(['order_detail' => function($query) {
        $fromDate = Carbon::now()->subMonth()->startOfMonth()->toDateString();
        $tillDate = Carbon::now()->subMonth()->endOfMonth()->toDateString();
        $parse_fromDate = Carbon::parse($fromDate.' 00:00:00');
        $parse_tillDate = Carbon::parse($tillDate.' 23:59:59');
        $query->with('order');
        $query->whereBetween('created_at',[$parse_fromDate,$parse_tillDate]);
    }])
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->whereYear('created_at', '>=', now()->year);
    }])
    ->with(['order_detail' => function($query) {
        $last_year = now()->year - 1;
        $query->with('order');
        $query->whereYear('created_at', '>=', $last_year);
    }])
    ->get();

【问题讨论】:

  • 我认为你的方法有点适得其反。如果您的代码按预期工作,您将执行 16 个查询,而您可以通过 3 个查询和对结果进行一些过滤来实现相同的结果。
  • @apokryfos,你能建议重做我的代码吗?我不知道这种方法最好的是什么。请帮忙

标签: laravel eloquent laravel-7 eloquent-relationship


【解决方案1】:

使用这种方法,您实际上是用链中的下一个“with”覆盖每个“with”,因此实际执行的唯一内容是最后一个“with”。

您需要做的是将这些查询分解为具有单独结果集的单独查询,因为在核心上,您似乎希望从具有不同条件的多个不同查询中获得结果。

$todays_orders = Product::where('status', 'active')
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->where('created_at', '>=', today());
    }])
    ->get();

$yesterdays_orders = Product::where('status', 'active')
    ->with(['order_detail' => function($query) {
        $query->with('order');
        $query->where('created_at', '>=', Carbon::yesterday());
    }])
    ->get();

... etc...

【讨论】:

  • 我无法将其分解为单独的查询。我只想把这个 with() 放在每个查询的数组中,但我不知道如何..
【解决方案2】:

使用查询:

$product_orders = Product::where('status', 'active')
   ->with([ 'order_detail' => function ($query) {
        $last_year = now()->year - 1;
        $query->whereYear('created_at', '>=', $last_year); 
    }, 'order_detail.order' ])->get();

$product_orders->each(function (Product $product) {
    $product->today_orders = $product->order_detail->where('created_at', '>=', Carbon::today());
    $product->today_orders = $product->order_detail->whereBetween('created_at', [ Carbon::yesterday(), Carbon::today() ]);
    $product->weeks_orders = $product->order_detail->whereBetween('created_at', [ Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek() ]);
    $product->last_weeks_orders = $product->order_detail->whereBetween('created_at', [ Carbon::now()->subWeek()->startOfWeek(), Carbon::now()->subWeek()->endOfWeek() ]);
     // and so on
});

那么在您看来,每个产品应该具有在each中设置的属性

【讨论】:

    【解决方案3】:

    我通过在模型中使用过滤器创建了自己的解决方案

    在控制器中

    $product_orders = Product::where('status', 'active')
        ->with('order_detail_today', 'order_detail_yesterday', 'order_detail_this_week',
            'order_detail_last_week','order_detail_this_month', 'order_detail_last_month',
            'order_detail_this_year', 'order_detail_last_year')->get();
    

    在模型中

    public function order_detail_today()
        {
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->where('created_at', '>=', today());
        }
        public function order_detail_yesterday()
        {
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->where('created_at', '>=', Carbon::yesterday());
        }
        public function order_detail_this_week()
        {
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->where('created_at', '>=', [now()->startOfWeek(), now()->endOfWeek()]);
        }
        public function order_detail_last_week()
        {
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->where('created_at', '>=', [now()->subWeek()->startOfWeek(), now()->subWeek()->endOfWeek()]);
        }
        public function order_detail_this_month()
        {
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->whereYear('created_at', '=', now()->year)
                ->whereMonth('created_at', '=', now()->month);
        }
        public function order_detail_last_month()
        {
            $fromDate = Carbon::now()->subMonth()->startOfMonth()->toDateString();
            $tillDate = Carbon::now()->subMonth()->endOfMonth()->toDateString();
            $parse_fromDate = Carbon::parse($fromDate.' 00:00:00');
            $parse_tillDate = Carbon::parse($tillDate.' 23:59:59');
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->whereYear('created_at', '=', now()->year)
                ->whereBetween('created_at',[$parse_fromDate,$parse_tillDate]);
        }
        public function order_detail_this_year()
        {
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->whereYear('created_at', '>=', now()->year);
        }
        public function order_detail_last_year()
        {
            $last_year = now()->year - 1;
            return $this->hasMany('App\Order_detail','reference_number')
                ->where('order_type', '!=', 'package')
                ->with('order')
                ->whereYear('created_at', '>=', $last_year);
        }
    

    【讨论】:

    • 通过这样做,您实际上是在拆分为单独的查询,因为每个关系(这就是您在此处所拥有的)本身就是一个单独的查询。所以没有真正的实际收获。 @apokryfos 的解决方案同样适用于单个查询,然后您只需在客户端上进行过滤。
    猜你喜欢
    • 1970-01-01
    • 2018-10-21
    • 2018-10-20
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2017-04-01
    • 2013-05-27
    相关资源
    最近更新 更多