Datamapper ORM / CodeIgniter - 使用和显示连接表

时间:2010-12-20 23:13:18

标签: php codeigniter codeigniter-datamapper

我有一个“步骤”表,其中包含“id”和名为“step”的步骤文本。然后我有一个“客户”表,其中包含“id”和其他客户信息。最后,我有一个“customers_steps”连接表,其中包含“customer_id”和“step_id”。目标是列出一个步骤列表,并显示哪些步骤已完成。但是我被卡住了......

为了确保我没有遗漏任何东西,在“客户”模型中,我有

var $has_many = array ('step');

在“步骤”模型中,我有

var $has_many = array('customer');

现在,我正在循环这些步骤,然后循环完成客户的步骤以查看它们是否匹配......但是这是很多代码,我知道必须有更快的方法,我只是想念它:

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

这有效......但我能做些什么才能让它变得更好?提前谢谢。

2 个答案:

答案 0 :(得分:1)

你有多对多的关系,所以你永远无法一次性完成这项任务。

理想情况下,您需要在steps和customers_steps之间进行LEFT JOIN,这将生成包含其中所有步骤的结果集,并为特定客户ID不存在的那些步骤生成NULL值。但由于Datamapper与关系有关,因此无法报告不存在的关系。

您可以使用

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

答案 1 :(得分:0)

在另一个案例中,我发现许多关系并不那么简单。也许,我要求太多魔术。

E.G。

客户has_many联系人has_many地址。

Contacts_Customers和Addresses_Contacts表的列为primary = 0或1。

我无法获得所有客户的完整表格,主要联系人和主要地址。

我可以通过主要联系人获取它们。当我使用第二个“where_join_field”时不起作用。也许我错过了什么......

我想要

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

没用。

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

另外,没有用。

我最终使用模型中的函数来过滤掉主要的0。本来希望上面的其中一个工作。至于实际的SQL命令,我想要的只是另一个WHERE addresses_contacts.primary = 1.