2016-09-29 196 views
-1

我正在重新編寫一個已編碼的「製作」系統,該系統基於一組數據庫「配方」,其中包含多達五個項目和數量(例如:item1item1qty)。現在以前按照正確的順序對配方中的物品進行排序很重要,這使得驗證變得簡單,因爲它只是查看用戶將item1item1qty等等放在哪裏,並將它們直接匹配。Laravel複雜查詢

我們希望現在以任意順序接受配料。我知道這可以通過查詢功能來完成,但是我擔心自己脫離了基礎,因爲我提出的解決方案將它標記爲有效的配方,如果用戶甚至有配方的一部分(比如說配方包含3種成分,只輸入其中一種成分即可,即使沒有其他2種適當的成分和量也是如此)。我的解決方案也很長,有沒有辦法簡化它?

$recipe = DataRecipe::where(function ($query) use($request) { 
     $query->where(function ($q) use($request) { 
      $q->where(function($q2) use ($request) { 
       $q2->where('item1', $request->item1)->where('item1qty', $request->item1qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item2', $request->item1)->where('item2qty', $request->item1qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item3', $request->item1)->where('item3qty', $request->item1qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item4', $request->item1)->where('item4qty', $request->item1qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item5', $request->item1)->where('item5qty', $request->item1qty); 
      }); 
     })->where(function ($q) use($request) { 
      $q->where(function($q2) use ($request) { 
       $q2->where('item1', $request->item2)->where('item1qty', $request->item2qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item2', $request->item2)->where('item2qty', $request->item2qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item3', $request->item2)->where('item3qty', $request->item2qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item4', $request->item2)->where('item4qty', $request->item2qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item5', $request->item2)->where('item5qty', $request->item2qty); 
      }); 
     })->where(function ($q) use($request) { 
      $q->where(function($q2) use ($request) { 
       $q2->where('item1', $request->item3)->where('item1qty', $request->item3qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item2', $request->item3)->where('item2qty', $request->item3qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item3', $request->item3)->where('item3qty', $request->item3qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item4', $request->item3)->where('item4qty', $request->item3qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item5', $request->item3)->where('item5qty', $request->item3qty); 
      }); 
     })->where(function ($q) use($request) { 
      $q->where(function($q2) use ($request) { 
       $q2->where('item1', $request->item4)->where('item1qty', $request->item4qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item2', $request->item4)->where('item2qty', $request->item4qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item3', $request->item4)->where('item3qty', $request->item4qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item4', $request->item4)->where('item4qty', $request->item4qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item5', $request->item4)->where('item5qty', $request->item4qty); 
      }); 
     })->where(function ($q) use($request) { 
      $q->where(function($q2) use ($request) { 
       $q2->where('item1', $request->item5)->where('item1qty', $request->item5qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item2', $request->item5)->where('item2qty', $request->item5qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item3', $request->item5)->where('item3qty', $request->item5qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item4', $request->item5)->where('item4qty', $request->item5qty); 
      })->orWhere(function($q2) use ($request) { 
       $q2->where('item5', $request->item5)->where('item5qty', $request->item5qty); 
      }); 
     }); 
    })->where('tool', $request->tool)->first(); 
+0

我是新來laravel /雄辯。所以我可能是錯的,但我認爲這可能會更容易編寫爲原始查詢。這絕對會更容易閱讀。另外,不確定你是否可以在Eloquent中使用它,但是MySQL會讓你搜索一個字符串'IN'多列(例如:'WHERE'胡蘿蔔'IN(item1,item2,item3,item4)' – CptMisery

回答

0

將有超過可能是一個更好的方式來做到這一點,但儘可能使你的代碼更易讀,你可以只使用一個循環:

$recipe = DataRecipe::where(function ($query) use ($request) { 

    foreach (range(1, 5) as $i) { 

     $item = $request->{'item' . $i}; 
     $quantity = $request->{'item' . $i . 'qty'}; 

     $query->where(function ($q) use ($item, $quantity) { 

      $q->where(function ($q2) use ($item, $quantity) { 
       $q2->where('item1', $item)->where('item1qty', $quantity); 
      })->orWhere(function ($q2) use ($item, $quantity) { 
       $q2->where('item2', $item)->where('item2qty', $quantity); 
      })->orWhere(function ($q2) use ($item, $quantity) { 
       $q2->where('item3', $item)->where('item3qty', $quantity); 
      })->orWhere(function ($q2) use ($item, $quantity) { 
       $q2->where('item4', $item)->where('item4qty', $quantity); 
      })->orWhere(function ($q2) use ($item, $quantity) { 
       $q2->where('item5', $item)->where('item5qty', $quantity); 
      }); 
     }); 
    } 

})->where('tool', $request->tool)->first(); 

如果有可能與你的應用程序,我會可能要考慮重構代碼和數據庫,以便在DataRecipe和項目之間建立標準的一對多關係。這樣你就不必擔心item1item2等,如果你只能有一定數量的項目,那麼你可以使用驗證,以確保你永遠不會得到太多。

希望這會有所幫助!