1

i have two tables:

  products       products_images
   -id            -id
   -name          -product_id
                  -image_name

There is one to many relation from product to products_images table

I have created two entities with its relation defined as: Product and ProductImage

I need to get list of products and its images but the limiting the record of no of images to 1.

Currently, I did this :

$product = $this->getDoctrine()
            ->getRepository('TestBundle:Product');

Then in the twig template:

{% for image in product.images if loop.first %}
{% endfor %}

I used this loop to fetch one image for that product. I dont think this is efficient way to do since i have fetching all the images for that product. What I want to do is just fetch only one image per product from the database? How can i do this ?

1 Answer 1

2

I'd add another method to the Product-entity, something like getThumbnail. This encapsulates the logic of which image is considered the thumbnail (i.e your view does not contain any logic of whether to display the first, last or any other product image, it just asks the product for its thumbnail):

in the view

{% if product.thumbnail %}
  {{ // Output the product.thumbnail-entity }}
{% endif %}

In the entity

public function getThumbnail ()
{
   return $this->getImages()->first();
}

Now, after profiling, if you're concerned that the full image collection is loaded when only a single image/product is shown, then I'd update the repository DQL to only fetch-join a single image, or make sure that the association to the images is EXTRA_LAZY

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, one more question, i have entity which has relation to 4-5 other entities. I could not understand the difference between lazy loading and extra lazy loading. By default, doctrine 2.1 has set lazy as default.Since I want doctrine to perform joins only when i access them like product.getImages(), which loading should I use: lazy or with extra lazy?
Doctrine does not use joins by default, calling getX performs another select against the database unless the collection has already been loaded with a previous DQL-statement upon hydration. EXTRA_LAZY enables you to not initialize the entire collection, by using the contains, count and slice-methods, which will increase performance by NOT loading an entire (large) collection into memory
Thanks for your quick response but I have a small problem. I have one to one relation from product entity to transaction entity and in product entity i added @ORM\OneToOne(targetEntity="Transaction", mappedBy="product",fetch="EXTRA_LAZY") for $transaction. Now when I fetch entity product, i looked into _profiler, I found that it performed left join to transaction entity. Why is that? am i missing something.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.