laravel 多对多链接 where 子句

laravel many to many with chaining where clause

我有给定的 table :

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

工具和零件之间的关系是多对多。部件和 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');

}

有什么想法吗??

使用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";
        }

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

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

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

}

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

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

我用 "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->partWithHighestTotalDelivery()tools.count次。如果工具很多,这是一个值得注意的过程。

而且,为了简单起见,我 post 的代码和我问的问题有一点 difference.that 的

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

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