Mam tabelę pytań i tabelę tagów. Chcę pobrać wszystkie pytania z tagów danego pytania. Na przykład mogę mieć przypisane do danego pytania tagi „Podróż”, „Pociągi” i „Kultura”. Chcę mieć możliwość pobrania wszystkich pytań dotyczących tych trzech tagów. Problem, jak się wydaje, polega na tym, że relacja między pytaniami i tagami jest zdefiniowana w elokwentnym elokwencji jako „naleŜycie do wielu”.
Myślałem o próbie scalenia kolekcji pytań, jak poniżej:
foreach ($question->tags as $tag) {
if (!isset($related)) {
$related = $tag->questions;
} else {
$related->merge($tag->questions);
}
}
Wydaje się jednak, że to nie działa. Wydaje się, że nic nie łączy. Czy robię to poprawnie? Czy jest też może lepszy sposób na pobranie wiersza wierszy w relacji wiele do wielu w elokwentnym?
php
laravel
eloquent
laravel-collection
Martyn
źródło
źródło
with
nie pomoże. TowhereHas
jest potrzebne - jak w odpowiedzi poniżej.Odpowiedzi:
Metoda merge zwraca scaloną kolekcję, nie powoduje mutacji oryginalnej kolekcji, dlatego należy wykonać następujące czynności
$original = new Collection(['foo']); $latest = new Collection(['bar']); $merged = $original->merge($latest); // Contains foo and bar.
Zastosowanie przykładu do kodu
$related = new Collection(); foreach ($question->tags as $tag) { $related = $related->merge($tag->questions); }
źródło
getKey
do łączenia wyników, więcModel::all()->merge(Model::all())->count() === Model::all()->count()
merge()
Metoda naCollection
nie zmodyfikować kolekcję, w którym została wywołana. Zwraca nowy zbiór ze scalonymi nowymi danymi. Potrzebujesz:Myślę jednak, że rozwiązujesz problem z niewłaściwej perspektywy.
Ponieważ szukasz pytań spełniających określone kryteria, prawdopodobnie łatwiej byłoby zadawać pytania w ten sposób.
has()
IwhereHas()
metody są wykorzystywane do generowania kwerendę opartą na istnieniu powiązanego rekordu.Gdybyś szukał tylko pytań, które mają jakikolwiek tag, użyłbyś tej
has()
metody. Ponieważ szukasz pytań z określonym tagiem, możesz użyć,whereHas()
aby dodać warunek.Tak więc, jeśli chcesz wszystkie pytania, które mają co najmniej jeden tag z „Podróż”, „Pociągi” lub „Kultura”, Twoje zapytanie będzie wyglądać następująco:
$questions = Question::whereHas('tags', function($q) { $q->whereIn('name', ['Travel', 'Trains', 'Culture']); })->get();
Jeśli chcesz, aby wszystkie pytania zawierały wszystkie te trzy tagi, zapytanie wyglądałoby następująco:
$questions = Question::whereHas('tags', function($q) { $q->where('name', 'Travel'); })->whereHas('tags', function($q) { $q->where('name', 'Trains'); })->whereHas('tags', function($q) { $q->where('name', 'Culture'); })->get();
źródło
źródło
Połącz dwie różne wymowne kolekcje w jedną, a niektóre obiekty będą miały ten sam identyfikator, jeden nadpisze inny. Zamiast tego użyj metody push () lub przemyśl swoje podejście do problemu, aby tego uniknąć. Zapoznaj się z siecią
źródło
Wszystkie nie działają u mnie na elokwentnych kolekcjach , laravel elokwentne kolekcje używają klucza z pozycji , które myślę, że powoduje problemy z łączeniem, musisz odzyskać pierwszą kolekcję jako tablicę, umieścić ją w nowej kolekcji, a następnie wrzucić pozostałe nowa kolekcja;
public function getFixturesAttribute() { $fixtures = collect( $this->homeFixtures->all() ); $this->awayFixtures->each( function( $fixture ) use ( $fixtures ) { $fixtures->push( $fixture ); }); return $fixtures; }
źródło
Tworząc nową kolekcję podstawową dla każdej elokwentnej kolekcji, scalanie działa dla mnie.
W tym przypadku nie miej conflits według kluczy podstawowych.
źródło