【问题标题】:Eloquent Filtering Collection with Eager Loading具有 Eager Loading 的 Eloquent 过滤集合
【发布时间】:2015-03-09 22:14:44
【问题描述】:

我一直在网上寻找,但似乎无法弄清楚这一点。 我有两张桌子:Teams 和 TeamMembers。一个团队可以有一个或多个团队成员,因此它是一对多的关系。

这是两张表的基本情况:

   class Team extends Base\EloquentBase
       {
          // Relationship
          public function teamMembers()
          {
            return $this->hasMany('TeamClock\Eloquent\Models\TeamMember', 'team_id', 'team_id');
          }
       }

       class TeamMember extends Base\EloquentBase
       {
          // Relationship
          public function team()
          {
            return $this->belongsTo('TeamClock\Eloquent\Models\Team', 'team_id', 'team_id');
          
          // Scope
          public function scopeHasDailyPerDiem($q)
          {
            return $q->where('is_daily_per_diem', '>', 0);
          }
       }

如您所见,我在 TeamMember 类中有一个范围,我想获取所有团队成员的列“is_daily_per_diem”大于 0 的团队。

我有一个测试控制器,我正在输出结果:

$teams = Team::has('teamMembers')->with(array('teamMembers' => function($query){
                $query->hasDailyPerDiem();
        }))->get();

这是我倾销时得到的:

[0] => Array
        (
            [team_id] => 55
            [phase_id] => value
            [team_name] => value
            [team_member_quota] => value
            [team_member_overstaff] => value
            [published] => value
            [tools_required] => value
            [dress_code] => value
            [special_instructions] => value 
            [team_members] => Array
                (
                )

        )
...
[41] => Array
        (
            [team_id] => 115
            [phase_id] => value
            [team_name] => value
            [team_member_quota] => value
            [team_member_overstaff] => 0
            [published] => 1
            [tools_required] => 
            [dress_code] => 
            [special_instructions] => 
            [team_members] => Array
                (
                    [0] => Array
                        (
                            [team_member_id] => value
                            [team_id] => 115
                            [position_id] => value
                            [employee_id] => value
                            [team_auth_id] => 1
                            [progress_auth_id] => 2
                            [is_daily_per_diem] => 1
                            [daily_per_diem] => 60.00
                            [pay_type_id] => 1
                            [flat_rate] => 
                            [is_active] => 0
                            [per_diem_beg_date] => 
                            [per_diem_end_date] => 
                            [beg_shift_id] => 
                            [end_shift_id] => 
                            [assign_email_guid] => value
                        )

                )

        )

如您所见,我得到了包含团队成员的团队(即每日每日津贴 > 0)和团队成员为空的团队。

有没有办法消除空队成员的团队?

我还在我的测试控制器中尝试了这个和其他东西:

$teams = Team::whereHas('teamMembers', function($query){
            $query->hasDailyPerDiem();
        })->get(); 

但这会返回一个包含“每日津贴”大于零的所有团队成员的数组,但我没有得到任何团队信息:

[0] => Array
        (
            [team_id] => 55
            [phase_id] => value
            [team_name] => value
            [team_member_quota] => value
            [team_member_overstaff] => value
            [published] => value
            [tools_required] => value
            [dress_code] => value
            [special_instructions] => value
        )
...
 [36] => Array
        (
            [team_id] => 115
            [phase_id] => value
            [team_name] => value
            [team_member_quota] => value
            [team_member_overstaff] => value
            [published] => value
            [tools_required] => value
            [dress_code] => value
            [special_instructions] => value
        )

非常感谢任何帮助!!!

【问题讨论】:

    标签: php orm eloquent


    【解决方案1】:

    你快到了……

    如果您想过滤团队和渴望加载成员:

    $teams = Team::with('teamMembers')->whereHas('teamMembers', function($query){
                 $query->hasDailyPerDiem();
             })->get(); 
    

    如果您想过滤团队和急于加载的成员:

    $teams = Team::with(['teamMembers' => function($query){
                 $query->hasDailyPerDiem();
             }])->whereHas('teamMembers', function($query){
                 $query->hasDailyPerDiem();
             })->get();
    

    如果要使用第二个代码块减少重复代码,请将过滤器闭包放在一个变量中:

    $filter = function($query){
        $query->hasDailyPerDiem();
    };
    
    $teams = Team::with(['teamMembers' => $filter])
                 ->whereHas('teamMembers', $filter)
                 ->get();
    

    【讨论】:

    • 谢谢!!!!第一个选项不起作用,因为我要让所有团队的团队成员有或没有每日津贴,但第二个是我需要的!!!
    • 不客气。但我很确定第一个会为您提供正确的团队,但无论每日津贴如何,都会与所有相关成员一起获得。无论如何,很高兴我能帮上忙!
    • 好的...我会更详细地研究它。与此同时,我得到了录取!
    【解决方案2】:

    定义一个实现Scope接口的类

    类 TeamFilterScope 实现范围{

         public function apply(Builder $builder, Model $model){
         $builder->hasDailyPerDiem()
        }
    }
    

    在你模特的靴子里

    protected function static boot(){
        parent::boot();
        static::addGlobalScope(new TeamFilterScope());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      • 2018-01-10
      • 2014-08-14
      相关资源
      最近更新 更多