2016-06-08 1 views
3

:Laravel 5 재귀 함수 대다 내가 다 대다 관계가 참조하는 다음 자기가 모델이라는 제품이 자기 참조 모델

// parent products based on the product_product pivot table 
public function parent_products() 
{ 
    return $this->belongsToMany('App\Product', 'product_product', 'child_id', 'parent_id')->withPivot('amount'); 
} 

// child products based on the product_product pivot table 
public function child_products() 
{ 
    return $this->belongsToMany('App\Product', 'product_product', 'parent_id', 'child_id')->withPivot('amount'); 
} 

// movements 
public function movements() 
{ 
    return $this->hasMany('App\Movement', 'product_id'); 
} 

그렇게 모든 제품은 "이상적"무한한 수를 조상 및 어린이.

또한 어떤 제품도 "구성 요소"와 같이 다른 제품의 구성물입니다.

그래서 각 어린이의 출석률과 제품을 만드는 데 필요한 금액을 기준으로 "생산 가능한"제품의 양을 반환해야합니다.

이것이 한 단계의 문제라면 아무런 문제가 없지만 시스템에서 많은 수위를 가질 수 있도록해야합니다. 그러면 어린이도 어린이에게서 만들 수 있습니다.

각 제품 -> 제품 -> 제품 체인의 깊이를 제어 할 수 없습니다.

성능 문제 외에도 체인의 각 제품에 "생산 가능한"양을 반환하는 재귀 적 방법이 필요합니다.

나는이

public function child_products_recursive() 
{ 
    return $this->child_products()->with(['child_products_recursive','movements'=>function($query){ 
    $query->whereDate('ready_date', '<=', date('Y-m-d'))->sum('amount'); 
    }]); 
} 

같은 체인의 마지막까지 반복적으로 아이들을 얻는 방법을 관리하고 그것을 작동합니다.

그러나이 값을 반환하는 방법이나 각 모델을 탐색하는 방법을 알 수 없습니다.

관여 테이블은 그런 "단순화"입니다

products 
--------- 
id | name 
--------- 
1 | something 
2 | something 
3 | something 
4 | something 
5 | something 
6 | something 
7 | something 


product_product 
----------------------------- 
parent_id | child_id | amount (amount of children in the parent product) 
----------------------------- 
1   | 2  | 2 
1   | 3  | 4 
2   | 4  | 1.5 
2   | 5  | 3 
4   | 6  | 0.7 
4   | 7  | 0.3 


movements table 
------------------------------------- 
id | product_id | date  | amount 
------------------------------------- 
1 | 4   | 2016-01-06 | 300 
2 | 5   | 2016-01-06 | 200 
3 | 6   | 2016-01-06 | 125 
4 | 7   | 2016-01-06 | 1000 

때문에 제품 ID 1은 운동을하지 않지만 움직임이없는 있지만이 될 수있는 아이 제품을 기반으로 여러 조각으로 만들 수 있습니다 어린이 제품으로도 제작할 수 있습니다. 사전에

  Wine box  Wine box 
      6 bottles  12 bottles ---1x-- Box for 
      of Wine3  of Wine4   12 Bottles 
      /\    | \   
      / \   | \ 
      x6  x1   |  x12 
      /  \   |  \ 
     Bottle  Box for |  Bottle 
     of Wine3 6 Bottles |  Label 
     /| \    |   
     / | \   /\  
    / | \   / \ 
    / |  \  / \ 
    x1 x0.75 x1  x12  x9 
    /  |  \ /  \ 
Empty  |  Bottle   Wine4 
Bottle XY |  Cork ABC 
      |   
      |   
      | 
      | 
      Wine3 
     / \ 
     / \ 
    x0.7  x0.3 
    /  \ 
    Wine1  Wine2 

감사 :

다음은 시각적 표현 (내가 전에 테이블의 데이터를 따라하지 못했지만, 단지 아이디어를 제공하기 위해)입니다. 챠오

+0

그래, 난 어떤 비슷한 문제를 얻었다 내 시도 – Alessandro

답변

0

나는 제품 isProducible 내가 좋아하는 뭔가를 제안하면 내가 생각을 알고 있지만, 테스트 해달라고 : 다른,

public function getIsProducibleAttribute() 
{ 
    if($this->movements > 0) 
     return true; 
    else{ 
     foreach($this->child_products_recursive as $child) 
     { 
      if(!$child->is_producible) 
       return false; 

      if($child->movements < $child->pivot->amount) 
       return false; 
     } 

     return true; 
    } 

} 

을 제품이 그래서는 이미 거기 운동이있는 경우 어린이를 확인하십시오. 이있는 경우금액이이고, 어린이가 반품되지 않는 경우 입니다.

나를 다시 해보자 :

public function getProducibleQuantityAttribute() 
{ 
    $quantity = 0; 
    foreach($this->child_products_recursive as $child) 
    { 
     //The production expected of that child with its stock and producible take in account. 
     $child_producible = ($child->movements + 
          $child->producible_quantity) 
          /$child->pivot->amount; 

     //The first value 
     if($quantity == 0) 
      $quantity = $child_producible; 
     //Takes the lowest 
     else if($child_producible < $quantity) 
      $quantity = $child_producible; 
    } 

    return $quantity ; 
    } 
} 

따라서, 나는 아이들의 재고 및 생산 가능 금액을 확인하고 단위를 만들기 위해 부모가 필요로하는 양으로 나눈 값. 가장 낮은 값을 얻습니다. 예를 들면 다음과 같습니다.

24 개의 병이 있지만 12 개의 상자 만 있으므로 대답은 1입니다.PS : 망가 라운드, 또는하지 잊지

)

+0

을보다 깨끗하고 간단한 해결책으로 해결 한 경우 내가 그 접근 방식으로 갈 것입니다하지만 궁금 생각 아니,이 품목의 몇 조각이 생산 가능한지 알아야합니다. – Alessandro

+0

좋아요, 운동은 주식입니까? 제품은 자식 제품들간에 교차점을 가질 수 있습니까? A는 B와 C로, B는 D로, C는 D와 E로 만들어 지므로 D를 사용하여 B를 만들려면 생산 가능 C를 할인해야합니다. –

+0

바로. 현재 날짜까지 제품과 관련된 움직임의 합계가 실제 주식을 나타내지 만,이 부분을 고려하지 않고 이미 값이 있다고 가정합니다. (추가를 사용하여 제품에 값을 추가한다고 생각합니다. 가지고있다). – Alessandro