问题
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?
回答1:
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!
回答2:
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);
回答3:
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;
}
}
来源:https://stackoverflow.com/questions/13054474/codeigniter-get-related-data-rows-as-structures-objects-not-array