2016-09-29 4 views
-1

Ich bin ein bereits codiertes "Crafting" -System nacharbeiten, die auf einer Reihe von Datenbank "Rezepte" basiert, die bis zu fünf Elemente und Mengen hat (zB item1 und item1qty). Jetzt war es wichtig, die Artikel im Rezept in der richtigen Reihenfolge zu bestellen, was die Validierung einfach machte, da es nur auf die Benutzer item1 und item1qty usw. schaute und sie direkt anpasste.Laravel komplexe Abfrage

Wir möchten jetzt haben es Zutaten in beliebiger Reihenfolge akzeptieren. Ich weiß, dass dies mit Abfragefunktionen erledigt werden kann, aber ich befürchte, dass ich von der Basis abweicht, da die von mir entwickelte Lösung es als gültiges Rezept kennzeichnet, wenn der Benutzer sogar einen Teil eines Rezepts hat (ein Rezept enthält beispielsweise 3 Zutaten) Geben Sie nur eine dieser Zutaten ein, die auch ohne die anderen 2 richtigen Zutaten und Mengen validiert wird. Meine Lösung ist auch ziemlich lang, gibt es eine Möglichkeit, es ein wenig zu straffen?

$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

Ich bin neu zu Laravel/eloquent. Ich könnte also falsch liegen, aber ich denke, das wäre wahrscheinlich viel einfacher als eine rohe Abfrage zu schreiben. Es wäre definitiv einfacher zu lesen. Auch, nicht sicher, ob Sie es in Eloquent tun können, aber MySQL wird Sie nach einer Zeichenfolge "IN" mehrere Spalten suchen lassen (zB: 'WHERE 'Karotten' IN (item1, item2, item3, item4)) – CptMisery

Antwort

0

Es wird mehr als wahrscheinlich ein besserer Weg, dies zu tun, aber so weit wie machen Sie Ihren Code lesbarer Sie nur eine Schleife verwenden: mit Ihrer Anwendung

$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(); 

Wenn es möglich ist, ich würde Wahrscheinlich sehen Sie sich Refactoring Code und Datenbank, so dass Sie nur eine Standard-1-2-Many-Beziehung zwischen DataRecipe und Elemente haben. Auf diese Weise müssen Sie sich keine Gedanken darüber machen, ob Sie item1, item2 usw. haben. Wenn Sie nur eine bestimmte Anzahl von Elementen haben können, können Sie einfach die Validierung verwenden, um sicherzustellen, dass Sie nie zu viele bekommen.

Hoffe, das hilft!