【问题标题】:Rails cannot delete or update a parent row: a foreign key constraint failsRails 无法删除或更新父行:外键约束失败
【发布时间】:2016-05-04 11:01:19
【问题描述】:

我想从我的数据库中删除一些东西。 该值引用了其他一些表。

错误是:

Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails

我该如何正确解决这个问题?

如果我在删除级联上添加一些约束,其他值不会被删除吗?

编辑:

def delete
   @vid = Movie.find params[:id]
   @vid.delete
   redirect_to :action => :add
end

更新模型

电影.rb

class Movie < ActiveRecord::Base
  has_many :comments, :dependent => :destroy
  has_many :ratings
  belongs_to :channel
  has_and_belongs_to_many :tags
  has_and_belongs_to_many :categories
  mount_uploader :video, MovieUploader

comment.rb

class Comment < ActiveRecord::Base
  belongs_to :movie
  belongs_to :user
  belongs_to :rating

【问题讨论】:

    标签: mysql ruby-on-rails ruby-on-rails-4 reference


    【解决方案1】:

    确保你的父 Model.rb 有

    has_many :model, :dependent => :delete_all 
    

    这可确保您在删除父模型后删除所有数据。

    比如你有 Post.rb 和 Comment.rb

    Post.rb

    has_many :Comments, :dependent => :delete_all
    

    所以,当你删除一个帖子时,所有相应的评论也会被删除。

    希望对你有帮助

    干杯

    【讨论】:

    • 谢谢,但没有任何效果。错误仍然出现
    • 你是怎么删除的?
    • 添加了我的删除功能oben
    【解决方案2】:

    如果您使用ActiveRecord::Migration 创建了外键,默认情况下它将使用ON DELETE RESTRICT(即与您想要的相反:如果存在行条目将被删除是引用其他表的条目)。

    您需要将迁移更改为使用ON DELETE CASCADE

    class CreateChild < ActiveRecord::Migration
      def change
        create_table :child do |t|
          t.references :parent, foreign_key: {on_delete: :cascade}
        end
      end
    end
    

    【讨论】:

      【解决方案3】:

      您使用的是delete,来自the documentation

      强制对象的 before_destroy 和 after_destroy 回调或 任何 :dependent 关联选项,请使用 #destroy。

      因此,您需要改用destroy,以便执行来自rails 的适当回调以删除相关记录:

      def delete
         @vid = Movie.find params[:id]
         @vid.destroy
         redirect_to :action => :add
      end
      

      因为您的 Comment 记录依赖于您尝试删除的 Movie 记录,因此,由于 rails 只是试图在 cmets 之前删除电影,如果评论中有外键,数据库引擎会抱怨表到电影表。

      【讨论】:

        【解决方案4】:

        错误: Mysql2::Error: 无法删除或更新父行:外键约束失败

        解决方案:

        我认为您使用过 .delete 或 delete_all,

        使用 .destroy 代替 .delete 或 delete_all

        .destroy 将删除与该模型相关的所有值

        【讨论】:

          【解决方案5】:

          您能否发布适用的数据库架构?

          如果您设置了删除级联约束,则其他值将被删除。如果这不是预期的结果,那么您可能需要重新考虑数据库的引用完整性。

          也许,您可能想考虑使用 ActsAsParanoid gem 来软删除元素?

          【讨论】:

          • 错误来自属于电影的 cmets。 Mysql2::Error: 无法删除或更新父行:外键约束失败 (dev.comments, CONSTRAINT fk_rails_56963e5c80 FOREIGN KEY (movie_id) REFERENCES movies (id)): DELETE FROM movies WHERE movies.id = 1 可以删除 cmets .. 所以我应该只添加 on delete 级联对吗?
          • 如果您打算在删除电影时删除 cmets,那么可以。你可以认为模型看起来像这样class Movie &lt; ActiveRecord::Base has_many :comments, dependent: :destroy end
          猜你喜欢
          • 2017-06-11
          • 1970-01-01
          • 2019-05-25
          • 2014-11-11
          • 2018-05-12
          • 2017-09-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多