Php CodeIgniter数据映射器保存一对多1:n
我正在使用codeigniter和datamapper创建一个发票应用程序 一张发票包含多个发票项 我正在尝试根据发票保存新的发票项目 如果我这样做:Php CodeIgniter数据映射器保存一对多1:n,php,codeigniter,codeigniter-datamapper,Php,Codeigniter,Codeigniter Datamapper,我正在使用codeigniter和datamapper创建一个发票应用程序 一张发票包含多个发票项 我正在尝试根据发票保存新的发票项目 如果我这样做: $invoice = new Invoice(1474); $invoice_item1 = new Invoice_item(); $invoice_item1->description = 'item 1'; $invoice_item2 = new Invoice_item(); $invoice_item2->desc
$invoice = new Invoice(1474);
$invoice_item1 = new Invoice_item();
$invoice_item1->description = 'item 1';
$invoice_item2 = new Invoice_item();
$invoice_item2->description = 'item 2';
$items = array($invoice_item1, $invoice_item2);
foreach ($items as $item) {
$item->save($invoice);
}
这很好,但我希望我能做这样的事情:
$invoice = new Invoice(1474);
$invoice_item1 = new Invoice_item();
$invoice_item1->description = 'item 1';
$invoice_item2 = new Invoice_item();
$invoice_item2->description = 'item 2';
$items = array($invoice_item1, $invoice_item2);
$invoice->save($items);
$invoice->save($invoice_item);
public function save() {
// passing arguments the way they came,
// it's also more robust against changes in datamapper with func_get_args() + call_user_func()
call_user_func_array(array('parent', 'save'), func_get_args());
$this->where('id', $this->id)->update('invoice_no', $this->id);
}
有可能这样做吗?非常感谢任何帮助或建议,谢谢
更新:
发票模型
class Invoice extends DataMapper {
public $has_many = array('invoice_item');
public $has_one = array('customer');
public function __construct($id = NULL) {
parent::__construct($id);
}
public function getTotal() {
$this->invoice_item->get_iterated();
$total = 0;
foreach ($this->invoice_item as $item) {
$total += $item->price * $item->qty;
}
return number_format($total, 2);
}
public function getStatus() {
if (!$this->paid) {
$status = date_diff(date_create(date('Y-m-d')), date_create($this->invoice_date))->format('%a') . " days";
} else {
$status = 'PAID';
}
return $status;
}
public function save() {
parent::save();
$this->where('id', $this->id)->update('invoice_no', $this->id);
}
}
发票项目模型
class Invoice_item extends DataMapper {
public $has_one = array('invoice');
public function __construct($id = NULL) {
parent::__construct($id);
}
}如果将magick
save{relationname}
函数与数组一起使用,它应该可以执行您想要的操作,请尝试:
$invoice->save_invoice_item($items);
如果将数组传递给save()
方法,它会尝试将其中的每一项解释为一个关系,要使“*-many”起作用,您需要在其中包含第二个数组,因此将发票项包装两次也可以:
$invoice->save(array(array($invoice_item1, $invoice_item2));
不幸的是,DM似乎无法处理相关对象尚未首先保存到数据库的情况(猜测正确的顺序并不容易)。所以你必须这样写:
$invoice_item1->save();
$invoice_item2->save();
$invoice->save(array(array($invoice_item1, $invoice_item2)));
保存后,这将使用发票的ID更新发票项目行。当然,这并不理想,因为有时数据库持有的发票项没有相关发票,建议在这里使用事务
您可以先保存不带项目的发票
,然后使用发票实例保存项目,从而切换订单:
$invoice->save();
$invoice_item = new Invoice_item;
// ...
$invoice_item->save($invoice);
您可以通过从$this->db->querys
转储查询来检查发生了什么
更新
在您的Invoice
模型中,您正在覆盖原始的save()
方法,但是您没有将参数传递给parent::save()
,因此如下行:
$invoice = new Invoice(1474);
$invoice_item1 = new Invoice_item();
$invoice_item1->description = 'item 1';
$invoice_item2 = new Invoice_item();
$invoice_item2->description = 'item 2';
$items = array($invoice_item1, $invoice_item2);
$invoice->save($items);
$invoice->save($invoice_item);
public function save() {
// passing arguments the way they came,
// it's also more robust against changes in datamapper with func_get_args() + call_user_func()
call_user_func_array(array('parent', 'save'), func_get_args());
$this->where('id', $this->id)->update('invoice_no', $this->id);
}
将忽略该参数(php不会抱怨需要更多参数)。
你可能想写这样的东西:
$invoice = new Invoice(1474);
$invoice_item1 = new Invoice_item();
$invoice_item1->description = 'item 1';
$invoice_item2 = new Invoice_item();
$invoice_item2->description = 'item 2';
$items = array($invoice_item1, $invoice_item2);
$invoice->save($items);
$invoice->save($invoice_item);
public function save() {
// passing arguments the way they came,
// it's also more robust against changes in datamapper with func_get_args() + call_user_func()
call_user_func_array(array('parent', 'save'), func_get_args());
$this->where('id', $this->id)->update('invoice_no', $this->id);
}
您最初的示例之所以有效,是因为您使用了
Invoice\u项class的save()
方法进行了保存。非常感谢您的回答。我尝试了你的两个建议,但似乎都没有保存相关的发票项目:(哦,我没有意识到,在保存发票项目的最终发票之前,您没有先保存发票项目。不幸的是,DM在将尚未存在的对象保存为关联对象时,似乎无法使用这些对象。更新了答案。再次感谢您的更新。但似乎仍然无法使用。感谢提示:$this->db->query是的。这真的很有用。我可以看到正在保存的发票项,但既没有$invoice->save\u invoice\u item($items);也没有$invoice->save(数组($invoice\u item1,$invoice\u item2)));更新发票id字段,使其与发票保持无关。在我的测试环境中,这两个字段都起作用。那么,关系中一定存在命名或其他问题。您是否可以发布模型或至少$有一个和$有多个部分(如果您使用这些部分,可能是$表)?我添加了对似乎正在发生的事情的解释。