Tengo una tabla de preguntas y una tabla de etiquetas. Quiero obtener todas las preguntas de las etiquetas de una pregunta determinada. Entonces, por ejemplo, puedo tener las etiquetas "Viajes", "Trenes" y "Cultura" adjuntas a una pregunta determinada. Quiero poder obtener todas las preguntas de esas tres etiquetas. Lo complicado, al parecer, es que la relación de preguntas y etiquetas es de muchos a muchos definida en Eloquent como pertenece a muchos.
Pensé en intentar fusionar las colecciones de preguntas de la siguiente manera:
foreach ($question->tags as $tag) {
if (!isset($related)) {
$related = $tag->questions;
} else {
$related->merge($tag->questions);
}
}
Sin embargo, no parece funcionar. No parece fusionar nada. ¿Estoy intentando esto correctamente? Además, ¿hay quizás una mejor manera de obtener una fila de filas en una relación de muchos a muchos en Eloquent?
php
laravel
eloquent
laravel-collection
Martyn
fuente
fuente
with
no ayudará. Es lowhereHas
que se necesita, como en la respuesta a continuación.Respuestas:
El método merge devuelve la colección fusionada, no muta la colección original, por lo que debe hacer lo siguiente
$original = new Collection(['foo']); $latest = new Collection(['bar']); $merged = $original->merge($latest); // Contains foo and bar.
Aplicando el ejemplo a su código
$related = new Collection(); foreach ($question->tags as $tag) { $related = $related->merge($tag->questions); }
fuente
getKey
a resultados de la combinación, por lo queModel::all()->merge(Model::all())->count() === Model::all()->count()
El
merge()
método enCollection
no modifica la colección en la que fue llamado. Devuelve una nueva colección con los nuevos datos combinados. Necesitaría:Sin embargo, creo que está abordando el problema desde el ángulo equivocado.
Dado que está buscando preguntas que cumplan con ciertos criterios, probablemente sería más fácil realizar consultas de esa manera. Los métodos
has()
ywhereHas()
se utilizan para generar una consulta basada en la existencia de un registro relacionado.Si solo estuviera buscando preguntas que tengan alguna etiqueta, usaría el
has()
método. Dado que está buscando preguntas con una etiqueta específica, usaríawhereHas()
para agregar la condición.Por lo tanto, si desea todas las preguntas que tienen al menos una etiqueta con 'Viajes', 'Trenes' o 'Cultura', su consulta se vería así:
$questions = Question::whereHas('tags', function($q) { $q->whereIn('name', ['Travel', 'Trains', 'Culture']); })->get();
Si quisiera todas las preguntas que tuvieran esas tres etiquetas, su consulta se vería así:
$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();
fuente
fuente
Combina dos colecciones elocuentes diferentes en una y algunos objetos tienen la misma identificación, una sobrescribirá a la otra. En su lugar, utilice el método push () o reconsidere su enfoque del problema para evitarlo. Consulte la web
fuente
No todos funcionan para mí en colecciones elocuentes , las colecciones elocuentes de laravel usan la clave de los elementos que creo que causan problemas de fusión, necesita recuperar la primera colección como una matriz, ponerla en una colección nueva y luego empujar las demás a la nueva colección;
public function getFixturesAttribute() { $fixtures = collect( $this->homeFixtures->all() ); $this->awayFixtures->each( function( $fixture ) use ( $fixtures ) { $fixtures->push( $fixture ); }); return $fixtures; }
fuente
Al crear una nueva colección base para cada colección elocuente, la combinación funciona para mí.
En este caso no tiene conflits por sus claves primarias.
fuente