0

I've got a little problem here. I have category_id for every product in DB. I also have a category table in DB for categories and their ID. Now i need to put in into view together. I've made add, edit and delete action, also show action, where is category showed with the rest of product description. But now I have a problem with an index action.

In show I did this:

public function getProductTable()
 {
    if (!$this->productTable) {
         $sm = $this->getServiceLocator();
         $this->productTable = $sm->get('Product\Model\ProductTable');
     }
     return $this->productTable;
 }

public function getCategoryTable() {
    if(!$this->categoryTable){
        $this->categoryTable = $this->getServiceLocator()
            ->get('Product\Model\CategoryTable');
    }
    return $this->categoryTable;
}

 public function showAction()
 {
    $id = (int) $this->params()->fromRoute('id', 0);
    if (!$id) {
         return $this->redirect()->toRoute('product', array(
             'action' => 'add'
         ));
    }

    try {
         $product = $this->getProductTable()->getProduct($id);
         $category = $this->getCategoryTable()->getCategory($product->category_id);
     }
     catch (\Exception $ex) {

         return $this->redirect()->toRoute('product', array(
             'action' => 'index'
         ));
     }

It's easy, cause during the show action I will get one result from DB, so I know exactly what category_id product has.

But, in index.html I will get all the products from DB and need to iterate them throughout Foreach. That's the place where I need to get a call

$this->getCategoryTable()->getCategory($id);

Since this is a controller method using the sm to use the model method, how should I use this in my index.html view to get the exact category name for every product?

Ammar Dje
  • 80
  • 1
  • 10
Michal Takáč
  • 1,005
  • 3
  • 17
  • 37

3 Answers3

1

It's massively inefficient to be calling a query to get the category names for each product individually, instead, write a method which will return an array of category names keyed by id in your CategoryTable class

public function getCategoryNames()
{
     // query to get list of names and ids

     // return array of category names, keyed by id
     $categories = array();
     foreach ($results as $result) {
          $categories[$result['id']] = $result['name'];
     }
     return $categories;
}

Call the method in your controller action and pass the result to the view ...

public function indexAction()
{
    $categories = $this->getCategoryTable()->getCategoryNames();
    $products = $this->getProductTable()->getProducts();
    return new ViewModel(array(
        'categories' => $categories,
        'products' => $products,
    ));
}

In your view, you can loop over your products, and simply access the category name by its id key in the $categories array

// index.phtml
<ul>
<?php foreach ($products as $product) : ?>
    <li>Product category  name is : <?= $categories[$product->category_id]; ?></li>
<?php endforeach; ?>
</ul>

The result is just two db calls, instead of one call to get products, and then an additional call to get the category name for each product item individually.

Crisp
  • 11,417
  • 3
  • 38
  • 41
  • Thanks a lot Crisp :) I was thinking about doing it this way, but somehow i got stuck, you really did help me. :) – Michal Takáč Apr 08 '14 at 09:23
  • zend 3 question: How can we fetch cms pages title and their links to display them in header / footer sections of entire website. Pages title and links are stored in database. Please share any suggestion. Thanks. – Kamlesh Feb 25 '20 at 14:05
0

Everything is working, but i would add for others, when I used your example, it threw error:

cant use object type as array

This happened, cause my query did not returned me $result['id'] and $result['name'] because i was using TableGateway and it did return $result->id and $result->name So final function looks like this:

public function getCategoryNames()
{
    $results = $this->fetchAll();
    $categories = array();

    foreach ($results as $result) {
        $categories[$result->id] = $result->name;
    }

    return $categories;
}

Everything else is working well as Crisp stated :)

Thanks a lot Crisp :)

Michal Takáč
  • 1,005
  • 3
  • 17
  • 37
0

well I think that you can render your result directly to your view since we are all working with MVC doing that is a little bit unclean since all of the logic is used on controllers and sometimes you need to slice your work on independent component well for that you create a function and like my friends, before me, they provide you syntax so you will write something like

public function name of your function()
{
    //fetching the result of your model query them all or one 
    return your result 

}

and in your view, you will have to get the value and print your result

Ammar Dje
  • 80
  • 1
  • 10