[DC-377] Cannot delete a taggable record (Taggable Extension) Created: 22/Dec/09  Updated: 10/Aug/12  Resolved: 15/Mar/10

Status: Closed
Project: Doctrine 1
Component/s: Extensions
Affects Version/s: 1.2.0, 1.2.1
Fix Version/s: 1.2.2

Type: Bug Priority: Major
Reporter: Fabien Pennequin Assignee: Jonathan H. Wage
Resolution: Fixed Votes: 1
Labels: None

PHP 5.3.1, Mac OS X (10.6), MySQL 5.0.86, Symfony 1.4.1

Attachments: Text File TaggableConstraintError.patch    


With Taggable extension, when I try to delete a record using Taggable, I get this exception :

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`sf_sandbox/article_taggable_tag`, CONSTRAINT `article_taggable_tag_id_article_id` FOREIGN KEY (`id`) REFERENCES `article` (`id`))

If I check the sql queries generated by Doctrine, there are not "onDelete CASCADE" for one of relation added by Taggable extension.

I have write some test cases for reproduce this bug (checking if relation has a property onDelete setted to CASCADE) but I can't reproduce the thrown exception in test case because sqlite omits queries with constraint. Also, I found how to fix this bug.

The fix and test cases are available in the file attached to this ticket.

Comment by Jason [ 20/Apr/10 ]

Hi Jon-

Where can I find this fix?

http://svn.doctrine-project.org/extensions/Taggable/branches/1.2-1.0 (the link referenced from the docs at http://www.doctrine-project.org/extension/Taggable) doesn't have this fix.

Comment by Jason [ 20/Apr/10 ]

Sorry, it appears the patch attached above is in SVN, however this is still broken.

With Doctrine 1.2.2 sandbox configured to work with MySQL 5.x database on 5.2.10, using the following schema

actAs: [Taggable]
type: string(255)
notnull: true
type: string(255)
notnull: true

the CASCADE in the constraints for the table being applied the Taggable behavior are still not being applied (see first constraint below)

CREATE TABLE `blog_post_taggable_tag` (
`id` bigint(20) NOT NULL DEFAULT '0',
`tag_id` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`,`tag_id`),
KEY `blog_post_taggable_tag_tag_id_taggable_tag_id` (`tag_id`),
CONSTRAINT `blog_post_taggable_tag_id_blog_post_id` FOREIGN KEY (`id`) REFERENCES `blog_post` (`id`),
CONSTRAINT `blog_post_taggable_tag_tag_id_taggable_tag_id` FOREIGN KEY (`tag_id`) REFERENCES `taggable_tag` (`id`) ON DELETE CASCADE ON UPDATE CASCADE

Comment by Malcolm Hall [ 10/Aug/12 ]

I use Doctrine v1.2.4 and created a fix for this problem, change the _options array initialization in Taggable.php to this:

protected $_options = array(
'builderOptions' => array(),
'tagField' => null,
'cascadeDelete' => true

This works because parent::buildRelation() calls the buildLocalRelation() method in Generator.php which looks for the cascadeDelete and if true then it adds the necessary CASCADE params, as you can see below:

public function buildLocalRelation($alias = null)
if (isset($this->_options['cascadeDelete']) && $this->_options['cascadeDelete'] && ! $this->_options['appLevelDelete'])

{ $options['onDelete'] = 'CASCADE'; $options['onUpdate'] = 'CASCADE'; }


Now both parts of the taggable relation get the cascade on delete feature. So if you delete a tag OR you delete a post, the row in the taggable_tag table gets deleted too.

Generated at Sun Oct 04 13:07:32 EDT 2015 using JIRA 6.4.10#64025-sha1:5b8b74079161cd76a20ab66dda52747ee6701bd6.