为什么这个连接打印没有正确的结果? Laravel 5.3

时间:2017-04-21 06:57:20

标签: php laravel-5.3

我们最近有一个承包商在我们的应用程序上做一些工作,现在我不得不调试它。我还是Laravel的新手,我正在努力调试这个问题。他们离开了新的牧场,无法提供帮助。

应该发生的是仅打印匹配的结果。因此,假设我们的代理商ID为141,他们有1个首选地区,东南亚。

让我们看看用户252,我们发现他们有多个首选地区,其中1个是东南亚地区。我只想返回匹配的区域。

目前尚未发生这种情况。 目前,超出用户252的偏好:
没有偏好 - 任何地区 东欧

我们得到的结果是: 东欧洲 东南亚

我的假设是这部分代码是罪魁祸首? SQL不是我的强项。

/**
         * Match regions with 2 given id's
         *
         * @return Array with the matched regions_id 
         * @author 
         **/
        public function matchRegions ($itemOne, $itemTwo)
        {
            return \App\Regionable::selectRaw('count(*) AS cnt, regions_id, description')
              ->join('regions', 'regions_id', '=', 'regions.id')                
              ->where('regionable_id', $itemOne)
              ->orWhere('regionable_id', $itemTwo)
              ->groupBy('regions_id')
              ->havingRaw('cnt > 1')
              ->get();
        }

        public function matchPreferences ($itemOne, $itemTwo)
        {
            return \App\Preferable::selectRaw('count(*) AS cnt, ministry__prefs_id, description')
              ->join('ministry_prefs', 'ministry__prefs_id', '=', 'ministry_prefs.id')                
              ->where('preferable_id', $itemOne)
              ->orWhere('preferable_id', $itemTwo)
              ->groupBy('ministry__prefs_id')
              ->havingRaw('cnt > 1')
              ->get();
        }

        public function matchLanguages($itemOne, $itemTwo)
        {
            return \App\Languageable::selectRaw('count(*) AS cnt, language_id, subcategory as description')
              ->join('languages', 'language_id', '=', 'languages.id')        
              ->where('languageable_id', $itemOne)
              ->orWhere('languageable_id', $itemTwo)
              ->groupBy('language_id')
              ->havingRaw('cnt > 1')
              ->get();
        }

        public function matchCommitment($itemOne, $itemTwo)
        {
            return \App\Timeable::selectRaw('count(*) AS cnt, time__commitment_id, timecommit.description')
              ->join('timecommit', 'time__commitment_id', '=', 'timecommit.id')
              ->where('timeable_id', $itemOne)
              ->orWhere('timeable_id', $itemTwo)
              ->groupBy('time__commitment_id')
              ->havingRaw('cnt > 1')
              ->get();
        }



public function prefCount ()
    {
      return (count($this->regions()->get())+count($this->ministry_prefs()->get())+count($this->languages()->get())+count($this->time_commitment()->get()));      
    }

    public function matchSeeker($userIds = [])
    {
      if(empty($userIds)) $userIds = UserInfo::all()->pluck('id');
      $agencyPrefCount = $this->prefCount();

      foreach ($userIds as $userId) {
        $seekerPrefCount = 0;
        $seeker = [];
        $regions = $this->matchRegions($this->id, $userId);
        $preferences = $this->matchPreferences($this->id, $userId);
        $languages = $this->matchLanguages($this->id, $userId);
        $timecommit = $this->matchCommitment($this->id, $userId);

        if(count($regions) > 0) $seeker['regions'] = $regions;
        if(count($preferences) > 0) $seeker['preferences'] = $preferences;
        if(count($languages) > 0) $seeker['languages'] = $languages;
        if(count($timecommit) > 0) $seeker['timecommit'] = $timecommit;


        if(!empty($seeker)) {
          $seeker['details'] = UserInfo::findOrFail($userId);
          $seekerPrefCount = (count($regions)+count($preferences)+count($languages)+count($timecommit));
          if(($agencyPrefCount == 0) || ($seekerPrefCount == 0)) $seeker['relevance'] = 0;
            else $seeker['relevance'] = round((($seekerPrefCount / $agencyPrefCount) * 100),2); 
          $seekers[$userId] = $seeker;
        }
      }


      $seekers = array_reverse(array_values(array_sort($seekers, function ($value) {
        return $value['relevance'];
      })));

      return $seekers;
    }

将结果打印到视图的工作原理如下:

控制器:

public function getDashboard() {

        $agency = Agency::with('ministry_prefs', 'languages', 'time_commitment', 'regions')->findOrFail(Auth::user()->login_id);
        $seekers = $agency->matchSeeker();
        return view('agency-area.home', compact('agency', 'seekers'));
    }

刀片:

@foreach($seekers as $seekerId => $seeker)
  <?php 
    switch (true) {
      case ($seeker['relevance'] <= 20) :
          $level = 'bg-red';
        break;
      case (($seeker['relevance'] >= 21) && ($seeker['relevance'] <= 30)):
          $level = 'bg-orange';
        break;
      default:
          $level = 'bg-green';
    }
  ?>

    <div class="box-comment">                
   {{ Html::image('img/avatar.jpg', 'User Image', array('class' => 'img-circle img-sm')) }}<!-- User image -->
      {{-- <button type="button" class="btn btn-default btn-xs"><i class="fa fa-thumbs-o-up"></i> Like</button> --}}
    <div class="comment-text">
      <span class="username">
        <a href="user/{{ $seeker['details']->id }}">{{((!empty($seeker['details']->name)) ? $seeker['details']->name : $seeker['details']->First_Name." ".$seeker['details']->Last_Name)}} {{$seeker['details']->First_Name." ".$seeker['details']->Last_Name}}</a>
        <span class="text-muted pull-right">{{$seeker['details']->created_at}}</span>
        {{-- <span class="badge {{$level}}">{{$seeker['relevance']}} % <span class="text-white">Match</span></span>          --}}
      </span><!-- /.username -->
        {{$seeker['details']->Experience}}


      <hr/>
      <div class="row">
                @if(!empty($seeker["regions"]))
            <div class="col-xs-3">
                        <h4>Regions</h4>                    
                        @foreach($seeker["regions"] as $region)
                            <small>{{$region->description}}</small><br/>
                        @endforeach
            </div>
                @endif

                @if(!empty($seeker["preferences"]))
            <div class="col-xs-3">
                        <h4>Preferences</h4>                    
                        @foreach($seeker["preferences"] as $preferences)
                            <small>{{$preferences->description}}</small><br/>
                        @endforeach
            </div>
                @endif

                @if(!empty($seeker["languages"]))
            <div class="col-xs-3">
                        <h4>Languages</h4>                  
                        @foreach($seeker["languages"] as $commitment)
                            <small>{{$commitment->description}}</small><br/>
                        @endforeach
            </div>
                @endif

                @if(!empty($seeker["timecommit"]))
        <div class="col-xs-3">
                            <h4>Commitment</h4>
                        @foreach($seeker["timecommit"] as $commitment)
                            <small>{{$commitment->description}}</small><br/>
                            {{-- {{$commitment->time__commitment_id}} --}}
                        @endforeach
            </div>
                @endif

      </div>

    </div> <!-- /.comment-text -->
  </div><!-- /.box-comment -->


@endforeach

1 个答案:

答案 0 :(得分:0)

好的,非常感谢@Antonis-Tsimourtos通过调试指导我正确的方向。

暂时放下我的解决方案(注意我还没有测试过这个问题有多少。这解决了问题,但我觉得这个问题效率不高)。

问题来自承包商使用的加入声明:

public function matchLanguages($itemOne, $itemTwo)
        {
            return \App\Languageable::selectRaw('count(*) AS cnt, language_id, subcategory as description')
              ->join('languages', 'language_id', '=', 'languages.id')        
              ->where('languageable_id', $itemOne)
              ->orWhere('languageable_id', $itemTwo)
              ->groupBy('language_id')
              ->havingRaw('cnt > 1')
              ->get();
        }

ItemOne和Two是要匹配的帐户的用户ID。如果您查看连接,它会比较它们,但不是过滤掉最终结果,而是使用where和orwhere来确定每个结果。那些使用laravel的人会认识到这也是不必要的,因为Laravel的关系会照顾到这里的一半查询。

解决方案是使用这些查询,如下所示:

public function matchLanguages($itemOne, $itemTwo)
{

    $languages1 = \App\UserInfo::find($itemOne)->languages()->get();

    $languages2 = \App\Agency::find($itemTwo)->languages()->get();

    return $languages1->intersect($languages2);
}

不幸的是,我并不急于加载这些关系,这可能是优化的下一步。但这需要稍微搜索一下代码。

希望有所帮助!