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?
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!
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);
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;
}
}