【问题标题】:laravel many to many with chaining where clauselaravel 多对多链接 where 子句
【发布时间】:2023-03-08 10:49:01
【问题描述】:

我有一张给定的桌子:

tools     toolparts      parts     part_details
-----     ---------      -----     ------------
id*       id*            id*       id*
name      tool_id        name      part_id
          part_id                  total (int) 
-----     ---------      -----     ------------

Tools 和 Parts 之间的关系是ManyToMany。并且parts和part_details之间的关系是一对多的。

使用 Laravel 模型,如何获得具有最大 part_details.total 的部分的工具??

//tool model
public function parts()
{
    return $this->belongsToMany('App\Part', 'tool_part');
}

//part model
public function tools()
{
   return $this->belongsToMany('App\Tool', 'tool_part')
}

public function details(){
    return $this->hasMany('App\Part_detail');
}

//partDetail model
public function part(){
    return $this->belongsTo('App\Part');
}

控制器

public function index()
{
  $tools = Tool::with('parts', 'parts.details')->has('parts')->get();
  return $tools;
}

我的预期是这样的:

控制器

public function index()
{
  $tool = Tool::with('SinglePartThatHasHigestTotalInPartDetail');

}

有什么想法吗??

【问题讨论】:

    标签: laravel many-to-many laravel-eloquent


    【解决方案1】:

    您可以使用Laravel aggregates进行查询以获得想要的结果,

    在您的代码中使用max() 函数,

    public function index()
    {
      $tool = Tool::with(['parts.part_details' => function ($query) {
          $max = $query->max('total');
          $query->where('total',$max);
      })->first();
    
    }
    

    我还没有测试过,但你可以这样做。

    如果您会遇到任何错误,请发表评论。

    【讨论】:

    • 让我再解释一下我的问题。根据我在问题中提到的细节,我试图实现的是:1 个工具有 1 个部分,其中总和最多。 (请注意,1 个工具有多个部分,因为它是多对多的)
    • 是的。你的问题和答案似乎不同。但没关系:)
    【解决方案2】:

    我用“hacky”方式管理我的问题。如果有人有更好更优雅的解决方案,请告诉我。

    //工具模型

    public function partWithHighestTotalDelivery($trans_date = null){
        if (is_null($trans_date)) {
            $trans_date = date('Y-m-d');
        }
    
        $parts = $this->parts;
    
        $highest_total_delivery = 0;
    
        foreach ($parts as $key => $part) {
            $part->detail;
    
            $total_delivery = $part->first_value;
    
            if (isset( $part->detail->total_delivery )) {
                $total_delivery += $part->detail->total_delivery;     
            }
    
            if ($highest_total_delivery < $total_delivery ) {
               $highest_total_delivery = $total_delivery;
    
               $part->total_delivery = $highest_total_delivery;
    
               $result = $part;
            }   
    
        }
    
        if (!isset($result)) {
            $result = null;
        }
    
        $this->part = $result;
    }
    

    在控制器中我有:

    public function index(Request $request){
        $tools = Tool::has('parts')
        ->get();
    
        $tools->each(function($tool){
          $tool->partWithHighestTotalDelivery();
        });
    
        return $tools;
    }
    

    有了这个,我需要运行tool-&gt;partWithHighestTotalDelivery() tools.count 次。如果工具很多,这需要一个明显的过程。

    而且,我发布的代码和我提出的问题略有不同。为了简单起见

    【讨论】:

      【解决方案3】:

      使用 hasManyThrough 关系获取与工具相关的所有零件详细信息,然后您可以逐条查看记录并获取工具零件的最高总数。

      // 工具模型

      public function partsdetails()
      {
          return $this->hasManyThrough('App\PartDetail', 'App\Part','tool_id','part_id');
      }
      

      在您的控制器中

      $data = Tool::all(); 
              $array = [];
              if(isset($data) && !empty($data)) {
      
                  foreach ($data as $key => $value) {
                     $array[$value->id] = Tool::find($value->id)->partsdetails()->max('total');
                  }
              }
      
              if(is_array($array) && !empty($array)) {
                  $maxs = array_keys($array, max($array));
                  print_r($maxs);// This array return the max total of the tool related parts
              } 
              else{
               echo "No Data Available";
              }
      

      【讨论】:

      • 使用这种方法,我需要运行 Tool::find($value->id)->partsdetails()->sum('total') 这么多次。和 sum() 不是我在这里需要的东西。
      • @punk73 您需要 part_details total 最高的工具 id。那么我的答案是正确的。因为 $maxs 返回的工具 ID 是 part_details 中最高的总和。
      • 我需要一个工具来包含一个part_details.total最高的部分;
      【解决方案4】:

      您可以从零件细节开始,然后从那里获取工具:

      $maxPartDetail = Part_detail::orderByDesc('total')->first();
      $tools = $maxPartDetail->part->tools;
      

      【讨论】:

        猜你喜欢
        • 2016-06-11
        • 2020-09-28
        • 2018-09-05
        • 1970-01-01
        • 1970-01-01
        • 2016-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多