Datamapper ORM/ CodeIgniter - using and displaying join tables
I've got a "steps" table, with the "id" and the text of the step named "step". Then I have a "customers" table with "id" and other customer info. Finally, I have a "customers_steps" join table with "customer_id" and "step_id". The goal is to have a list of steps, and show which ones were completed. But I'm stuck...
To make sure I'm not missing anything, in the "customer" model, I have
var $has_many = array ('step');
In the "step" model, I have
var $has_many = array('customer');
Right now, I'm looping the steps, then looping through the customer's steps to see if they match... but it's a lot of code, and I KNOW there has to be a faster way, and I'm just missing it:
$c = new Customer();
$c->get_by_id(1);
$c->step->get();
$s = new Step();
$s->get();
foreach($s as $step)
{
foreach($c as $customer)
{
if($customer->step->id == $step->id)
{
$match = true;
}
}
if($match)
{
echo "match - " . $step->step;
}
else
{
echo $step->step;
}
}
This works... but what can I do to make it better? Thanks in adv开发者_StackOverflow社区ance.
You have a many-to-many relationship, so you'll never be able to do this in one go.
Ideally, you need a LEFT JOIN between steps and customers_steps, which would produce a resultset with all steps in it, and a NULL value for those steps not present for a specific customer id. But since Datamapper is about relationships, it can't report relations that aren't there.
You could use
// get the customer and his steps
$c = new Customer(1);
$c->step->get();
// create the list of assigned step id's
$list = array();
foreach ($c->step as $step)
{
$list[] = $step->id;
}
// get the steps not assigned
$s = new Step();
$s->where_not_in('id', $list);
// at this point $c->steps contains all matching steps
// and $s all steps that don't match
print_r($c->steps->all_to_array());
print_r($s->all_to_array());
On a different case, I have found many to many relationships not so straightforward. Maybe, I'm asking for too much magic.
E.G.
Customers has_many Contacts has_many Addresses.
Contacts_Customers and Addresses_Contacts tables have a column primary = 0 or 1.
I am not able to get a full table of all customers, with primary contact and primary addresses.
I can get them with primary contacts. Doesn't work when I use a second "where_join_field". Maybe I'm missing something...
I wanted
$c = new Customer();
$c->include_related('contact');
$c->where_join_field('contact','primary','1');
$c->include_related('contact/address');
$c->where_join_field('contact/address','primary','1');
$c->get();
Didn't work.
$c = new Customer();
$c->include_related('contact');
$c->where_join_field('contact','primary','1');
$c->contact->include_related('address');
$c->contact->where_join_field('address','primary','1');
$c->get();
Also, didn't work.
I ended up using a function within the model to filter out the primary 0s. Would have liked one of the above to work though. As for the actual SQL command, all I wanted was another WHERE addresses_contacts.primary = 1.
精彩评论