Codeigniter - get related data rows as structures/

2019-08-07 17:59发布

Im a newbie in CodeIgniter.

I have created model for Pizza table and Ingredients table. Tables are joined by additional Pizza_Ingredients table (its many to many relation).

My model:

<?php

class Pizza extends DataMapper {

    var $table = 'Pizza';

    var $has_many = 
        array(
        'ingredients' => 
            array(
            'class' => 'ingredients',
            'join_table' => 'pizza_ingredients'
            )
        );
}

class Ingredients extends DataMapper {

    var $table = 'Ingredients';
    var $has_many = 
        array(
            'pizza' => 
                array(
                'class' => 'pizza',
                'join_table' => 'pizza_ingredients'
             )
        );
}

?>

When I get data using that code:

$pm = new Pizza();
$pm->include_related('ingredients');
$array = $pm->get();

im getting array which has duplicated Pizza values (it looks like just sql query result).

margherita    | cheese
vegetariana   | vegetable 1
vegetariana   | vegetable 2

I can't simple generate html table in "foreach" on array like this.

i want to get object, that has structure like this:

margherita:
 - cheese

vegetariana:
 - vegetable 1
 - vegetable 2

that allows me to make foreach loop (with pizzas) with other foreach loop (with ingredients) inside "pizza loop".

I have to write this in PHP, or CodeIgniter/DataMapper can do something more for me?

Any advice?

3条回答
孤傲高冷的网名
2楼-- · 2019-08-07 18:39

You could set a variable that is the pizza you are currently on and check it on your next iteration. Your formatting and whatnot would vary but this will give you an idea.

foreach ($pizza as $k=>$p) {
    if ($last_pizza === $p->pizza) {
        echo "<tr>
            <td>
            </td>
        </tr>
        <tr>
            <td>
                $p->cheese
            </td>
        </tr>";
        $last_pizza = $p->pizza;
    }else{
        echo "<tr>
            <td>
                $p->pizza
            </td>
        </tr>
        <tr>
            <td>
                $p->cheese
            </td>
        </tr>";
        $last_pizza = $p->pizza;
    }
}
查看更多
我想做一个坏孩纸
3楼-- · 2019-08-07 18:50

I'm just stuck in the same answer...

So, searching the CI Datamapper DOCs, I found something that will help (http://datamapper.wanwizard.eu/pages/getadvanced.html), look at the first example!

Translating to your problem, should be like this:

    // Create pizza

    $pm = new Pizza();

    // DO NOT USE include_related to Ingredients Here !!!
    //Datamapper will DO THIS for you!
    // Remember to declare your Ingredients class in singular, not plural
    // So your class should be in singular -> Ingredient
    // And your DB Table should be in plural -> Ingredients
    // As CI Datamapper Guide teaches :)

    // Get all pizzas

    $pm->get();

    // Loop through all pizzas

    foreach ($pm as $pizza)
    {

    // Print the actual pizza name

            echo $pizza->name."<br/>";

            // Get the current pizza's Ingredients  <- Here is the magic comes!

            $pizza->ingredient->get();

            // Print all current pizza's Ingredients

            foreach ($pizza->ingredient as $ingredient)
            {
                    echo $ingredient->name."<br/>";
            }
    }

This work very well to me, but it continues to hit the db a lot of times, actually, one time for each pizza that your DB contains.

I really appreciate if some solution using CI Datamapper took less requests to DB.

Please share if you find it!

查看更多
地球回转人心会变
4楼-- · 2019-08-07 19:00

Why not use an intermediary table to break down the many to many relationship. Seems much easier to manage. Like:

TABLE pizza_ingredients
   id
   pizza_id
   ingredient_id

Then you can try something like this:

foreach($pizzas as $pizza)
    $pizza->ingredients = $this->get_ingredients($pizza->id);
查看更多
登录 后发表回答