通过链接

时间:2018-04-16 02:40:18

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

我有一张特定的桌子:

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

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

}

任何想法?

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

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

}

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

评论您是否会收到任何错误。

答案 2 :(得分:0)

我以“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次。如果工具很多,这需要注意的过程。

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

答案 3 :(得分:0)

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

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