with wherepivot updateorcreate meaning hasmany example php orm laravel eloquent

php - wherepivot - Laravel Eloquent clasificación por columna de tabla de relación



wherepivot laravel (2)

Traté de clasificar los productos de la tabla shop_products por la columna shop_products_options tabla shop_products_options :

$products = Shop/Product::with([''options'' => function ($query) { $query->orderBy(''pinned'', ''desc''); }])->paginate(5);

Establecí la relación en el modelo Tienda / Producto:

public function options() { return $this->hasOne(''Shop/Options''); }

Pero los productos no están clasificados. Recibo una consulta que solo funciona con la tabla shop_products_options .

SELECT * FROM `shop_products_options` WHERE `shop_products_options`.`product_id` in (''8'', ''9'', ''10'', ''11'', ''12'') ORDER BY `pinned` DESC

¿Como arreglarlo?


La carga ansiosa utiliza consultas separadas, por lo que necesita unirse para esto:

$products = Shop/Product::join(''shop_products_options as po'', ''po.product_id'', ''='', ''products.id'') ->orderBy(''po.pinned'', ''desc'') ->select(''products.*'') // just to avoid fetching anything from joined table ->with(''options'') // if you need options data anyway ->paginate(5);

SELECT cláusula SELECT está allí para no agregar columnas unidas a su modelo de Product .

editar: según el comentario de @alexw: aún puede incluir columnas de tablas unidas si las necesita. Puede agregarlos para select o llamar addSelect/selectRaw etc.


No puede ordenar por columna de tabla relacionada sin la tabla relacionada de unión manual. La respuesta de Jarek es correcta, pero esto podría ser muy incómodo:

1. El primer problema es que debe preocuparse por seleccionar.

->select(''products.*'')

razón: sin select () id de shop_products_options se puede seleccionar e hidratar en el modelo del Producto.

2. El segundo problema es que debes preocuparte por groupBy.

->groupBy(''products .id'');

razón: si la relación es HasOne y hay más de una shop_products_options para el producto, la consulta devolverá más filas para los productos.

3. El tercer problema es que debe cambiar todas las cláusulas where where de:

->where(''date'', $date)

a

->where(''products .date'', $date)

razón: los productos y shop_products_options pueden tener el atributo "date" y en ese caso sin seleccionar el atributo con la tabla "ambiguous column" se generará un error.

4. El cuarto problema es que estás usando nombres de tablas (no modelos) y esto también es malo e incómodo.

->where(''products.date'', $date)

5. El quinto problema es que debe preocuparse por las eliminaciones suaves para las tablas unidas. Si shop_products_options usa el rasgo de SoftDeletes, debe agregar:

->where(''shop_products_options .deleted_at'', ''='', null)

Todos los problemas anteriores son muy frustrantes y unir tablas con elocuentes puede presentarle muchos problemas al código. Creé un paquete que se encarga de todos los problemas anteriores y puede ordenar por atributo de relación de manera elegante, para su caso sería:

$products = Shop/Product::orderByJoin(''options.pinned'', ''desc'')->paginate(5);

Para obtener más información, consulte https://github.com/fico7489/laravel-eloquent-join