Usar SELECT anidados en Eloquent

Veamos una de las características de Eloquent que más pasan desapercibidas al hacer búsquedas anidadas.

Usar SELECT anidados en Eloquent
Photo by Michael Dziedzic / Unsplash

Imagina que tenemos una tienda online con categorías y productos. Cada categoría puede ser "featured", y queremos tener una sección donde mostramos los productos de dichas categorías.

Se me ocurre una forma fácil de obtener estos productos:

$featuredCategories = Category::featured()->get();
$products = Product::whereIn('category_id', $featuredCategories->pluck('id'))->get();

Esta solución usaría 2 queries a la base de datos: una para obtener las categorías relevantes y otra para buscar los productos de dichas categorías.

Sin embargo, algo que no se conoce mucho de Eloquent es que le puedes pasar instancias del Query Builder como parámetro a las funciones where:

$products = Product::whereIn('category_id', Category::select('id')->featured())->get();

A diferencia de la anterior solución, esta última solamente ejecutaría una única query a la base de datos, muy parecida a esta:

SELECT *
FROM `products`
WHERE
	`category_id` IN (
    	SELECT `id`
        FROM `categories`
        WHERE `is_featured`=1
    )