La separación de SQL, PHP y la vista al enumerar las categorías y productos en Kohana

StackOverflow https://stackoverflow.com/questions/1498893

  •  19-09-2019
  •  | 
  •  

Pregunta

Quiero migrar a Kohana con mis pequeños sitios web y estoy tratando de separar el SQL, PHP y la vista, pero tengo algunos problemas con éste.

Tengo a las tablas. Cada categoría puede tener múltiples productos.

Categorías tabla

  • id
  • categoría

tabla Productos

  • id
  • category_id
  • producto

Esta fue mi código anterior (convertido en generador de consultas de Kohana):

        $categories = DB::select('id', 'category')
            ->from('categories')
            ->as_object()
            ->execute();

    foreach ($categories as $category)
    {
        echo '<b>'.$category->category.'</b><br />';
        $products = DB::select('product')
                ->from('products')
                ->where('category_id', '=', $category->id)
                ->as_object()
                ->execute();

        foreach($products as $product)
        {
            echo $product->product.'<br />';
        }
        echo '<hr />';
    }

Quiero hacer lo mismo, sólo en el archivo de vista no quiero a los usos distintos a cabo repitiendo las variables.

Actualización: Yo preferiría una solución sin necesidad de utilizar el módulo de ORM Kohana. Por cierto estoy usando Kohana 3.0

Actualización 2:

He aceptado la última solución de Lukasz, pero se requieren algunas modificaciones para hacer exactamente lo que quería (tenga en cuenta que esto es para Kohana 3.0, mientras Lukasz estaba trabajando con una versión más antigua):

código SQL:

$products = DB::select(array('categories.category', 'cat'), array('products.product', 'prod'))
                ->from('categories')
                ->join('products','RIGHT')
                ->on('products.category_id','category.id')
                ->as_object()
                ->execute();

Código en el archivo de vista (ver comentarios para la explicación):

        // Let's define a new variable which will hold the current category in the foreach loop
        $current_cat = '';
    //We loop through the SQL results
    foreach ($products as $product)
    {
        // We're displaying the category names only if the $current_cat differs from the category that is currently retrieved from the SQL results - this is needed for avoiding the category to be displayed multiple times
        // At the begining of the loop the $current_cat is empty, so it will display the first category name
        if($curren_cat !== $product->cat)
        {
            // We are displaying a separator between the categories and we need to do it here, because if we display it at the end of the loop it will separate multiple products in a category
            // We avoid displaying the separator at the top of the first category by an if statement
            if($current_cat !== '')
            {
                //Separator
                echo '<hr />';
            }
            // We echo out the category
            echo '<b>'.$product->cat.'</b><br />';
            // This is the point where set the $current_cat variable to the category that is currently being displayed, so if there's more than 1 product in the category the category name won't be displayed again
            $current_cat = $product->cat;
        }
        // We echo out the products
        echo $product->prod.'<br />';
    }

Espero que esto era útil a los demás, así, si alguien tiene una solución mejor seguir, compartir!

¿Fue útil?

Solución

Esto debería funcionar:

$categories = ORM::factory('category')->find_all();

foreach ($categories as $category)
{
    echo '<b>'.$category->category.'</b><br />';
    $products = ORM::factory('product')->where('category_id',$category->id)->find();

    foreach($products as $product)
    {
        echo $product->product.'<br />';
    }
    echo '<hr />';
}

Asumo que ha creado modelos para cada tabla? Si no, lea aquí .

Mejor si separa las capas de datos y ver. Y crear relaciones entre categorías y productos en archivos del Modelo. Luego, en el controlador debe llamar sólo esto:

$categories = ORM::factory('category')->find_all();
$view = new View('yourView');
$viem->categories = $categories;

Y en archivo de vista:

foreach ($categories as $category)
{
    echo '<b>'.$category->category.'</b><br />';

    foreach($category->products as $product)
    {
        echo $product->product.'<br />';
    }
    echo '<hr />';
}

Usted no tendrá que llamar segunda consulta para cada fila. Kohana ORM lo hará por ti. Todo lo que tiene que hacer es crear modelos adecuados:

class Category_Model extends ORM {
    protected $has_many = array('products');
}

class Product_Model extends ORM {
    protected $belongs_to = array('category');
}

Otro enfoque: se puede unir tablas categorías y productos

$products = DB::select('categories.category AS cat','products.product AS prod')
                    ->from('categories')
                    ->join('products','products.category_id','category.id')
                    ->as_object()
                    ->execute();

Y a continuación:

$current_cat = '';

foreach($products as $product)
{
    if($current_cat != $products->cat)
    {
        echo '<b>'.$products->cat.'</b><br />';
        $current_cat = $products->cat;
    }

    echo $product->prod.'<br />';
}

Otros consejos

Es sólo una idea rápida:

Cuando se utiliza el ORM-enfoque, creo que se podría lograr lo mismo que una consulta de unión con el con () Método:

$products = ORM::factory('product')
  ->with('category')
  ->find_all();
$view = new View('yourView');
$viem->products = $products;

No he tenido tiempo suficiente para perder el tiempo con ella, pero esto es lo que me gustaría probar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top