草庐IT

php - 与 Symfony 和 Doctrine 的 ON DELETE CASCADE 的多对多关系

coder 2023-10-16 原文

我想要与 Symfony 和 Doctrine 建立简单的多对多关系。这实际上是一个单向的一对多关联,可以通过连接表映射为 the docs indicate。我正在使用 YAML 文件通过以下代码对其进行配置:

在文件 Content.orm.yml 中:

manyToMany:
  comments:
    cascade: ["persist","remove"]
    onDelete: CASCADE
    options:
      cascade:
        remove: true
        persist: true
        #refresh: true
        #merge: true
        #detach: true
    orphanRemoval: false
    orderBy: null
    targetEntity: Comment
    joinTable:
      name: content_comments
      joinColumns:
        content_id:
          referencedColumnName: id
      inverseJoinColumns:
        comment_id:
          referencedColumnName: id
          unique: true

这会产生以下 SQL 命令:

$ php app/console doctrine:schema:update --dump-sql | grep -i "comment\|content"
CREATE TABLE comment (id INT AUTO_INCREMENT NOT NULL, text LONGTEXT NOT NULL, content_id INT NOT NULL, creation_date DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE contents (id INT AUTO_INCREMENT NOT NULL, user INT DEFAULT NULL, user_id INT NOT NULL,file VARCHAR(255) DEFAULT NULL, INDEX IDX_B4FA11778D93D649 (user), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE content_comments (content_id INT NOT NULL, comment_id INT NOT NULL, INDEX IDX_D297CC584A0A3ED (content_id), UNIQUE INDEX UNIQ_D297CC5F8697D13 (comment_id), PRIMARY KEY(content_id, comment_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE contents ADD CONSTRAINT FK_B4FA11778D93D649 FOREIGN KEY (user) REFERENCES users (id);
ALTER TABLE content_comments ADD CONSTRAINT FK_D297CC584A0A3ED FOREIGN KEY (content_id) REFERENCES contents (id);
ALTER TABLE content_comments ADD CONSTRAINT FK_D297CC5F8697D13 FOREIGN KEY (comment_id) REFERENCES comment (id);

但如您所见,FOREIGN KEY 指令没有“ON DELETE CASCADE”部分,即使我尝试放置我找到的所有 YAML 注释。

因为在代码中,我试图删除一个“内容”实体以及与此代码关联的所有“评论”:

        $comments = $content->getComments();

        // Remove first the parent
        $entity_manager->remove($content);
        $entity_manager->flush();

        // Remove the childs
        foreach($comments as $comment)
        {
            $entity_manager->remove($comment);
        }

        $entity_manager->flush();

这会产生以下异常。

An exception occurred while executing 'DELETE FROM comment WHERE id = ?' with params [1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`bb2server`.`content_comments`, CONSTRAINT `FK_D297CC5F8697D13` FOREIGN KEY (`comment_id`) REFERENCES `comment` (`id`))

那么,我做错了什么?或者如何强制 Doctrine 在多对多关系中加入“ON DELETE CASCADE”?

我唯一的肮脏解决方法是删除 SQL 查询并自己重建,但我需要 Doctrine 在 schema:update 中创建查询以避免我的修补:

mysql> show create table content_comments;
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table            | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| content_comments | CREATE TABLE `content_comments` (
  `content_id` int(11) NOT NULL,
  `comment_id` int(11) NOT NULL,
  PRIMARY KEY (`content_id`,`comment_id`),
  UNIQUE KEY `UNIQ_D297CC5F8697D13` (`comment_id`),
  KEY `IDX_D297CC584A0A3ED` (`content_id`),
  CONSTRAINT `FK_D297CC584A0A3ED` FOREIGN KEY (`content_id`) REFERENCES `contents` (`id`),
  CONSTRAINT `FK_D297CC5F8697D13` FOREIGN KEY (`comment_id`) REFERENCES `comment` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> ALTER TABLE content_comments DROP FOREIGN KEY FK_D297CC5F8697D13;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE content_comments ADD CONSTRAINT FK_D297CC5F8697D13 FOREIGN KEY (`content_id`) REFERENCES `contents` (`id`) ON DELETE CASCADE;
Query OK, 10 rows affected (0.07 sec)
Records: 10  Duplicates: 0  Warnings: 0

编辑:解决方法。我需要将 onDelete: CASCADE 放在 JoinColumns 下

manyToMany:
  comments:
    cascade: ["persist","remove"]
    onDelete: CASCADE
    options:
      cascade:
        remove: true
        persist: true
        #refresh: true
        #merge: true
        #detach: true
    orphanRemoval: false
    orderBy: null
    targetEntity: Comment
    joinTable:
      name: content_comments
      joinColumns:
        content_id:
          referencedColumnName: id
          onDelete: CASCADE
      inverseJoinColumns:
        comment_id:
          referencedColumnName: id
          unique: true
          onDelete: CASCADE

最佳答案

您必须像这样在“joinColumns”和“inverseJoinColumns”中添加“JoinColumn”定义:

/**
 * @var Collection|null
 * @ManyToMany(targetEntity="...")
 * @JoinTable(name="...",
 *     joinColumns={@JoinColumn(name="`...`", referencedColumnName="id", onDelete="CASCADE")},
 *     inverseJoinColumns={@JoinColumn(name="`...`", referencedColumnName="id", onDelete="CASCADE")}
 * )
 */

在那里你可以添加 onDelete 级联(数据库级别)定义

关于php - 与 Symfony 和 Doctrine 的 ON DELETE CASCADE 的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31830131/

有关php - 与 Symfony 和 Doctrine 的 ON DELETE CASCADE 的多对多关系的更多相关文章

  1. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  2. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  3. ruby - Rails 组合多个 activerecord 关系 - 2

    我想合并多个事件记录关系例如,apple_companies=Company.where("namelike?","%apple%")banana_companies=Company.where("namelike?","%banana%")我想结合这两个关系。不是合并,合并是apple_companies.merge(banana_companies)=>Company.where("namelike?andnamelike?","%apple%","%banana%")我要Company.where("名字像?还是名字像?","%apple%","%banana%")之后,我会写代

  4. ruby-on-rails - Ruby on Rails - has_one 关系,如何检查它是否具有现有关联? - 2

    我有一个简单的问题,与关联有关。我有一个书的模型,它有_onereservation。预订属于_书本。我想在预订Controller的创建方法中确保在预订时没有预订一本书。换句话说,我需要检查该书是否存在任何其他预订。我该怎么做?编辑:Aaa我做到了,感谢大家的提示,学到了一些新东西。当我尝试提供的解决方案时,出现no_method错误或nil_class等。这让我开始思考,我尝试处理的对象根本不存在。Krule给了我使用book.find的想法,所以我尝试使用它。最终我得到了它的工作:book=Book.find_by_id(reservation_params[:book_id])

  5. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  6. ruby-on-rails - Ruby/Rails - 检查 HABTM 关系记录中是否存在子 ID - 2

    我有一组名为Tasks和Posts的资源,它们之间存在has_and_belongs_to_many(HABTM)关系。还有一个连接它们的值的连接表。create_table'posts_tasks',:id=>falsedo|t|t.column:post_id,:integert.column:task_id,:integerend所以我的问题是如何检查特定任务的ID是否存在于从@post.tasks创建的数组中?irb(main):011:0>@post=Post.find(1)=>#@post.tasks=>[#,#]所以我的问题是,@post.tasks中是否存在"@task

  7. Ruby On Rails 模型、 View 和 Controller 之间的关系 - 2

    根据我目前的理解,如果我必须描述Rails应用程序的各个组件如何协同工作以响应请求,我会说以下内容:1)路由确定哪些请求URL映射到哪些Controller方法。2)Controller方法从模型中获取信息并将该信息(以全局变量的形式)传递给相应的View模板。3)View模板使用存储在全局变量中的数据来构造最终响应。在上面的解释中,几个组件之间的关系是明确的,不可否认的;即:1)路由和Controller方法2)Controller方法和View模板其实上面的关系是一对一的。但是,模型类与其相邻组件类型(即Controller)的关系并不明确。是的,Controller从模型中检索信

  8. ruby-on-rails - 本地 gem 的“bundle 安装”没有解决依赖关系,而 'gem install' 可以 - 2

    我在目录“/home/enterprise/pkg”中有一个本地gem(enterprise-0.0.1.gem)。它依赖于active_directorygem(v1.5.5),这是在它的enterprise.gemspec文件中指定的,如下所示:-gem.add_dependency("active_directory")在我的应用程序的Gemfile中,我添加了以下行:-gem'enterprise','0.0.1',path=>'/home/enterprise/pkg'当我做的时候bundleinstall在我的应用程序的源目录中,只安装了企业gem。因此,我遇到了引用act

  9. ruby-on-rails - 如何添加具有额外列的多对多记录 - 2

    我有以下模型用户has_many:users_contactshas_many:contacts,through::users_contactsaccepts_nested_attributes_for:contacts,allow_destroy:true联系方式has_many:users_contactshas_many:users,through::users_contactsaccepts_nested_attributes_for:users_contacts,allow_destroy:true用户联系belongs_to:usersbelongs_to:contacts

  10. ruby-on-rails - Rails/Mongoid 与 Struct 的关系问题 - 2

    我正在构建这个图书馆应用程序,它有3个类。国家、图书馆和书籍。国家有许多图书馆,图书馆属于一个国家。图书馆有很多书,书是嵌入图书馆的。但是,当我执行此auto_pick_job时,我们到达top_free_book并调用library.state。由于某种原因,library.state为nil。我希望恢复状态但没有骰子。我调用和创建库的方式如下。所以图书馆将永远属于一个现有的国家。state=Stats.find(x)library=state.libaries.new(info)library.save_optimistic!我也很感激使用Struct的关系帮助。classStat

随机推荐