Laravel:hasMany关系使用where子句

时间:2019-02-16 12:07:40

标签: laravel eloquent where-clause

这是我的第一个Laravel项目,所以也许我误会了一些东西。

我有ClientsCampaigns控制器,并且为客户设置了hasMany个广告系列

class Client extends Model
{
    public function campaigns(){

        return $this->hasMany('App\Campaign');

    }
}

在“客户端显示”方法中,此查询无效:

$client = Client::find($id);
$campaigns = $client->campaigns
                 ->where(function($query) use($startdate, $enddate) {
                     $query->wherebetween('start_date', [$startdate, $enddate])
                           ->orwherebetween('end_date', [$startdate, $enddate]);
                 })
                 ->sortBy('start_date')
                 ->groupBy(function($val) {
                     return Carbon::parse($val->start_date)->format('F Y');
                 });

我得到了错误: explode() expects parameter 2 to be string, object given 错误页面在})子句后的orwhereBetween上显示红线。

但是此查询确实有效:

$campaigns = DB::table('campaigns')
                 ->where('client_id', $client->id)
                 ->where(function($query) use($startdate, $enddate) {
                     $query->wherebetween('start_date', [$startdate, $enddate])
                           ->orwherebetween('end_date', [$startdate, $enddate]);
                 })
                 ->orderBy('start_date')
                 ->get()
                 ->groupBy(function($val) {
                     return Carbon::parse($val->start_date)->format('F Y');
                 });

我的问题是,一旦进入显示视图,第二个查询就不允许我访问$campaign->tasks

那么,有人知道为什么访问$client->campaigns时where子句会引起问题,而使用DB时却不会吗?

1 个答案:

答案 0 :(得分:1)

这是因为在调用 get 方法之前,该对象是 Eloquent Builder 类的实例,并且 groupBy 方法不接受任何参数作为关闭。但是,在调用get方法之后,它将更改为 Collection 类的实例,该类也具有 groupBy 方法,并且它接受闭包。

顺便说一下 sortBy 不属于雄辩的构建器,相反,您必须先使用 orderBy 才能使用 get执行查询方法。

以下是收集的可用方法

https://laravel.com/docs/5.7/collections#available-methods

尝试一下此代码,别忘了调用方法驼峰式案例,否则会给您带来严重的部署问题。

 $dates = $client->campaigns()
        ->where(function($query) use($startdate, $enddate) {
            $query->whereBetween('start_date', [$startdate, $enddate])
                ->orWhereBetween('end_date', [$startdate, $enddate]);
        })
        ->orderBy('start_date')
        ->get()
        ->groupBy(function($val) {
            return Carbon::parse($val->start_date)->format('F Y');
        });
        foreach($dates as $campaigns){
           foreach($campaigns as $campaign){
             dump($campaign->tasks);
           }
        }