2009-09-24 14 views
6

Tôi có hành vi softdelete của học thuyết gắn liền với tất cả các mô hình của tôi. Có cách nào tôi có thể xóa một bản ghi cụ thể không?Làm cách nào để tách một hành vi trong Symfony/Doctrine?

Trong CakePHP, tôi nhớ đã tách hành vi ... xóa bản ghi và sau đó đính kèm lại hành vi.

Có điều gì tương tự trong symfony/doctrine không? Nếu vậy thì làm thế nào để tôi tách một hành vi?

Chúc mừng

Trả lời

9

nghĩ tôi muốn đi cho cách Zed, nhưng cho đầy đủ:

Phương pháp nghe tổ chức sự kiện cho xóa (và chọn) cho hành vi xóa mềm chứa:

if (! $query->contains($field)) { 
    // do the magic stuff to covert the query to respect softdelete 
} 

Điều này có nghĩa rằng nếu bạn đề cập rõ ràng trường trong truy vấn, nó sẽ không áp dụng chuyển đổi cho truy vấn.

Vì vậy, nếu bạn làm:

$q = Doctrine_Query::create() 
->delete('Table t') 
->where('t.id = ? AND t.deleted != 2 ', 1); 

nó sẽ không áp dụng các công cụ xóa mềm mại và thực sự sẽ xóa hồ sơ. Lưu ý rằng bạn có thể làm bất cứ điều gì với t.deleted, tôi đã thực hiện một cái gì đó mà sẽ luôn luôn là đúng sự thật. Bí danh ('t.') Cũng quan trọng để nó hoạt động.

Thủ thuật này cũng phù hợp với các lựa chọn, đây là nơi tôi thường sử dụng trước đây.

Như tôi đã nói, mặc dù tôi nghĩ rằng nó đẹp hơn để làm:

$old_dqlc = Doctrine_Manager::getInstance()->getAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS); 
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, false); 
$record->delete(); 
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, $old_dqlc); 

Đặc biệt, bạn vẫn có thể sử dụng phương pháp xóa() thay vì phải tự tạo các truy vấn. Một điểm cộng cho phương thức truy vấn là nếu bạn có các hành vi khác gắn liền với hồ sơ, chúng sẽ vẫn được tôn trọng.

+1

Có lẽ bạn nên lưu trữ giá trị trước đó của Doctrine :: ATTR_USE_DQL_CALLBACKS thay vì đặt thành false và true. Điều gì xảy ra nếu CALLBACKS bị tắt trước khi mã đó gặp phải? –

+0

vâng ... tôi nên ... chỉnh sửa. – benlumley

+0

(mặc dù nếu callbacks tắt, xóa mềm không hoạt động) – benlumley

1

Hãy thử gọi điện thoại này, nó sẽ vô hiệu hóa xử lý hành vi.

$manager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, false); 

Là cách bẩn, bạn có thể tạo truy vấn SQL xóa mục nhập khỏi bảng.

+0

nah .. tôi nghĩ rằng đó là bẩn !! .. thanks anyway mặc dù .. – Yashvit

+0

OK. Hãy thử cuộc gọi tôi đã thêm. Đã không thử nó, nhưng tôi đoán nó sẽ làm việc. – Zed

+0

cool .. sẽ cho rằng một đi ... – Yashvit

1

link text tôi sẽ nghĩ rằng chức năng này và thiết lập sử dụng gọi lại dql sai giống như trên người quản lý nên làm các trick :).

13

umm .. các SoftDelete behavior bao gồm một cách đẹp hơn nhiều để làm điều này ... chỉ cần gọi

$record->hardDelete(); 
+0

có - đề nghị điều này được chấp nhận trước ý tưởng của tôi. Tôi đã bắt đầu sử dụng điều này. – benlumley

1

Wanted đồng ý với Joshua Coady rằng cách tốt nhất là nên sử dụng

$record->hardDelete() 

Tuy nhiên, tôi cũng muốn thêm ở đây vì đây là một trong những kết quả đầu tiên trên google để tách hành vi trong học thuyết là cách dễ nhất để tách hành vi cho "lựa chọn" chỉ đơn giản là bao gồm "deleted_at" (hoặc bất kỳ tên nào bạn đã đặt tên cho trường của mình) như trong truy vấn. Người nghe nhìn e nếu nó được bao gồm và nếu như vậy không lọc các bản ghi đã xóa.

Doctrine_Core::getTable('Record')->createQuery()->select('id, etc1, etc2')->addSelect('deleted_at')->execute(); 

sẽ trả về các bản ghi đã xóa.

5

$object->getListener()->setOption('disabled',true);

Điều này sẽ vô hiệu hóa tất cả người nghe bản ghi đối tượng này.

Các vấn đề liên quan