Tôi muốn tạo bản sao sâu/bản sao của một bản ghi học thuyết trong một dự án symfony. Phương thức sao chép ($ sâu) hiện tại không hoạt động đúng với $ deep = true.bản sao sâu của hồ sơ giáo lý
Ví dụ, chúng ta hãy xem bài học trên lớp học. Bài học này có ngày bắt đầu và ngày kết thúc và giữa chúng có một số lần ngắt. Lớp học này đang được xây dựng.
bài học-break là mối quan hệ một-nhiều, vì vậy rất nhiều giờ nghỉ có thể nằm trong một bài học. xây dựng bài học là mối quan hệ nhiều người, do đó, một bài học chỉ có thể ở trong ONE Building.
Nếu tôi muốn sao chép căn phòng, các điểm ngắt cũng phải được sao chép. Tòa nhà nên giữ nguyên (không có bản sao ở đây).
Tôi đã tìm thấy một số ví dụ trên web tạo lớp PHP mở rộng từ sfDoctrineRecord và ghi đè phương thức sao chép.
Những gì tôi cố gắng là:
class BaseDoctrineRecord extends sfDoctrineRecord {
public function copy($deep = false) {
$ret = parent::copy(false);
if (!$deep)
return $ret;
// ensure to have loaded all references (unlike Doctrine_Record)
foreach ($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if ($relation->getType() == Doctrine_Relation::MANY) {
if (empty($this->$name))
$this->loadReference($name);
// do the deep copy
foreach ($this->$name as $record)
$ret->{$name}[] = $record->copy($deep);
}
}
return $ret;
}
}
Bây giờ điều này gây ra trong một thất bại: Doctrine_Connection_Mysql_Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY'
Vì vậy, tôi cần phải "null" id của bản ghi mới ($ ret) vì đây phải là một kỷ lục mới. Tôi nên làm ở đâu và như thế nào?
UPDATE: Các lỗi được cố định với đoạn mã sau:
class BaseDoctrineRecord extends sfDoctrineRecord {
public function copy($deep = false) {
$ret = parent::copy(false);
if($this->Table->getIdentifierType() === Doctrine_Core::IDENTIFIER_AUTOINC) {
$id = $this->Table->getIdentifier();
$this->_data[$id] = null;
}
if(!$deep) {
return $ret;
}
// ensure to have loaded all references (unlike Doctrine_Record)
foreach($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if($relation->getType() == Doctrine_Relation::MANY) {
if(empty($this->$name)) {
$this->loadReference($name);
}
// do the deep copy
foreach($this->$name as $record) {
$ret->{$name}[] = $record->copy($deep);
}
}
}
return $ret;
}
}
Nhưng nó không hoạt động tốt. Trong bài học DoctrineCollection-> Breaks tất cả các ngắt mới đều ổn. Nhưng chúng không được lưu trong cơ sở dữ liệu. Tôi muốn sao chép một bài học và thêm 7 ngày để đó là thời gian:
foreach($new_shift->Breaks as $break) {
$break->start_at = $this->addOneWeek($break->start_at);
$break->end_at = $this->addOneWeek($break->end_at);
$break->save();
}
Vì vậy, như bạn thấy, các vi phạm được lưu, nhưng có vẻ như họ không nằm trong db.
Tôi đã viết một phương pháp cụ thể cho các nhu cầu của mình. Các giải pháp chung sản xuất nhiều vấn đề hơn là nó giải quyết ... Vâng, hiện tại nó không giải quyết bất kỳ vấn đề ở tất cả :) – hering