symfony - orderby - Cómo hacer un pedidoPor OneToMany/ManyToOne
doctrine onetomany order by (5)
Bueno, se me ocurrió algo así como un hack ... Como realmente solo me importa el tipo de salida, hice una extensión básica
use Doctrine/Common/Collections/Collection;
public function sort(Collection $objects, $name, $property = null)
{
$values = $objects->getValues();
usort($values, function ($a, $b) use ($name, $property) {
$name = ''get'' . $name;
if ($property) {
$property = ''get'' . $property;
return strcasecmp($a->$name()->$property(), $b->$name()->$property());
} else {
return strcasecmp($a->$name(), $b->$name());
}
});
return $values;
}
Sin embargo, me gustaría evitar este truco y todavía me gustaría conocer una solución real
Tengo una clase de Producto que tiene muchos campos para ManyToMany, como ingredientes, tamaños, especies, etc. Un total de aproximadamente 14 campos diferentes. No todos los campos son relevantes para cada producto.
Tengo una configuración de mapas como esta
Class product {
/**
* @var Species[]
* @ORM/ManyToMany(targetEntity="Species")
* @ORM/JoinTable(name="product_species",
* joinColumns={@ORM/JoinColumn(name="productId", referencedColumnName="id")},
* inverseJoinColumns={@ORM/JoinColumn(name="speciesId", referencedColumnName="id")}
* )
* @ORM/OrderBy({"name" = "asc"})
*/
private $species;
Esto funciona muy bien para muchos / muchos a uno.
El problema está en mi tabla product_ingredients. Necesito agregar un campo adicional, lo que significa que necesito cambiar de ManyToMany a OneToMany / ManyToOne.
/**
* @var ProductIngredient[]
*
* @ORM/OneToMany(targetEntity="ProductIngredient", mappedBy="product")
* @ORM/JoinColumn(name="productId", referencedColumnName="id")
*/
private $ingredients;
Ahora mi ProductIngredient Entity se parece a esto
/**
* @var IngredientType
* @ORM/ManyToOne(targetEntity="IngredientType", fetch="EAGER")
* @ORM/JoinColumn(name="ingredientTypeId", referencedColumnName="id")
*/
private $ingredientType;
/**
* @var Ingredient
*
* @ORM/ManyToOne(targetEntity="Ingredient", inversedBy="products", fetch="EAGER")
* @ORM/JoinColumns({
* @ORM/JoinColumn(name="ingredientId", referencedColumnName="id")
* })
*/
private $ingredient;
/**
* @var Product
*
* @ORM/ManyToOne(targetEntity="Product", inversedBy="ingredients")
* @ORM/JoinColumns({
* @ORM/JoinColumn(name="productId", referencedColumnName="id")
* })
*/
private $product;
Entonces en mi clase de producto para especies utilizo @ORM / OrderBy para que la especie ya esté ordenada. ¿Hay alguna forma en que de alguna manera también pueda hacer esto para mi campo de ingredientes?
¿O estoy haciendo mal mi lógica y estos no deberían ser campos en la clase de producto y deberían estar buscando en el repositorio?
Quería que fuera fácil, así que podía recorrer mis objetos como $product->getIngredients()
lugar de hacer
$ingredients = $this->getDoctrine()->getRepository(''ProductIngredient'')->findByProduct($product->getId());
Como me indicaron en una pregunta similar, debe escribir una consulta de combinación para que el orden ORM funcione, vea aquí para referencia. http://www.krueckeberg.org/notes/d2.html
Sin embargo, resolví mi problema con un plugin de ordenación de consulta en el lado del cliente, jquery datatable y tinysort son excelentes :-)
Deberías usar la opción ''query_builder'' en tu Formulario: http://symfony.com/doc/master/reference/forms/types/entity.html#query-builder El valor de la opción puede ser algo como esto:
function(EntityRepository $er) {
return $er->createQueryBuilder(''i'')->orderBy(''i.name'');
}
No olvide agregar la declaración "use" para EntityRepository
Si usa la asignación xml, podría usar
<order-by>
<order-by-field name="some_field" direction="ASC" />
</order-by>
dentro de tu etiqueta <one-to-many>
.
en la entidad Producto simplemente también agregue el pedido Por la relación de ingredientes
/**
* ...
* @ORM/OrderBy({"some_attribute" = "ASC", "another_attribute" = "DESC"})
*/
private $ingredients;