Frage

Ich mag Kohana mit meinen kleinen Websites wandern und ich versuche, die SQL, PHP und die Ansicht zu trennen, aber ich habe einige Probleme mit diesen.

Ich habe auf Tabellen. Jede Kategorie kann mehrere Produkte haben.

Tabelle Kategorien

  • id
  • Kategorie

Produkte Tabelle

  • id
  • category_id
  • Produkt

Dies war meine vorherigen Code (umgerechnet auf Kohana der Query Builder):

        $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 />';
    }

Ich möchte das gleiche tun, nur in der View-Datei Ich möchte nicht andere verwenden, als aus dem Variablen Echo.

Update: Ich würde eine Lösung bevorzugen, ohne Kohana ORM-Modul. Btw verwende ich Kohana 3.0

Update 2:

Ich habe Lukasz der letzte Lösung, aber ein paar Änderungen angenommen nötig sind, um genau das zu tun, was ich wollte (beachten Sie, dass dies für Kohana 3.0, während Lukasz mit einer älteren Version gearbeitet):

SQL-Code:

$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();

-Code in der Ansichtsdatei (siehe Kommentar zur Erklärung):

        // 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 />';
    }

Ich hoffe, dass dies hilfreich war auch für andere, wenn jemand eine bessere Lösung gehen hat, teilen Sie es!

War es hilfreich?

Lösung

Dies sollte funktionieren:

$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 />';
}

Ich gehe davon aus, dass Sie für jede Tabelle Modelle erstellt? Wenn nicht, lesen Sie hier .

Bessere , wenn Sie Daten und Ansicht Schichten trennen. Und schaffen Beziehungen zwischen Kategorien und Produkten in Modelldateien. Dann in der Steuerung sollten Sie nennen dies nur:

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

Und in View-Datei:

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

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

Sie werden nicht zweite Abfrage für jede Zeile rufen müssen. Kohana ORM wird es für Sie tun. Alles, was Sie tun müssen, ist geeignete Modelle zu erstellen:

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

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

Ein weiterer Ansatz: Sie können Tabellen Kategorien und Produkte verbinden

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

Und dann:

$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 />';
}

Andere Tipps

Nur ein kurzer Gedanke:

Wenn der ORM-Ansatz, ich glaube, Sie das gleiche wie eine Join-Abfrage erreichen könnten unter Verwendung des mit () Methode:

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

Ich habe nicht genug Zeit, um Chaos, um mit ihm gehabt, aber das ist, was ich versuchen würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top