ActiveRecord :: StatementInvalid:Mysql2 :: Error:无法删除或更新父行–Rails 4.2.6

需要解决的错误:

ActiveRecord :: StatementInvalid:Mysql2 :: Error:无法删除或更新父行:外键约束失败( slap_chat_development ,CONSTRAINT fk_rails_496733c195 FOREIGN KEY( group_id )REFERENCES groupsid )):DELETE FROM groups WHERE groupsid = 1

问题是:

  • 有人可以指导我从哪里修复此错误。

我看到问题在groupschatrooms表之间的关系中持续存在。

更多详情:

schema.rb

 ActiveRecord::Schema.define(version: 20160606100750) do create_table "chatrooms", force: :cascade do |t| t.integer "group_id", limit: 4 t.string "name", limit: 255 t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "chatrooms", ["group_id"], name: "index_chatrooms_on_group_id", using: :btree create_table "chatrooms_users", force: :cascade do |t| t.integer "chatroom_id", limit: 4 t.integer "user_id", limit: 4 t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "chatrooms_users", ["chatroom_id"], name: "index_chatrooms_users_on_chatroom_id", using: :btree add_index "chatrooms_users", ["user_id"], name: "index_chatrooms_users_on_user_id", using: :btree create_table "groups", force: :cascade do |t| t.string "name", limit: 255 t.integer "user_id", limit: 4 t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "groups", ["user_id"], name: "index_groups_on_user_id", using: :btree create_table "groups_users", force: :cascade do |t| t.integer "group_id", limit: 4 t.integer "user_id", limit: 4 t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "groups_users", ["group_id"], name: "index_groups_users_on_group_id", using: :btree add_index "groups_users", ["user_id"], name: "index_groups_users_on_user_id", using: :btree create_table "posts", force: :cascade do |t| t.integer "user_id", limit: 4 t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "content", limit: 255 end add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree create_table "users", force: :cascade do |t| t.string "email", limit: 255, default: "", null: false t.string "encrypted_password", limit: 255, default: "", null: false t.string "reset_password_token", limit: 255 t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.integer "sign_in_count", limit: 4, default: 0, null: false t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip", limit: 255 t.string "last_sign_in_ip", limit: 255 t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "first_name", limit: 255 t.string "nick_name", limit: 255 t.string "last_name", limit: 255 end add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree add_foreign_key "chatrooms", "groups" add_foreign_key "chatrooms_users", "chatrooms" add_foreign_key "chatrooms_users", "users" add_foreign_key "groups", "users" add_foreign_key "groups_users", "groups" add_foreign_key "groups_users", "users" add_foreign_key "posts", "users" end 

团体模特:

 class Group < ActiveRecord::Base has_many :chatrooms belongs_to :group_admin, class_name: "User", foreign_key: :user_id has_and_belongs_to_many :members, class_name: "User", association_foreign_key: :user_id validates :user_id, presence: true validates :name, presence: true, length: { minimum: 3 } before_create { self.name = self.name.capitalize } after_create :assign_creator around_destroy :destroy_all_associates def general_room self.chatrooms.where("name = ?", "general").take end def except_general_room self.chatrooms.select { |room| room != self.general_room } end def assign_creator member = self.group_admin self.members << member self.general_room.members << member end def destroy_all_associates rooms = self.chatrooms yield rooms.each do |room| room.destroy end end end 

聊天室型号:

 class Chatroom < ActiveRecord::Base belongs_to :group has_and_belongs_to_many :members, class_name: "User", association_foreign_key: :user_id validates :name, presence: true, length: { minimum: 3 } before_save { self.name = self.name.downcase } around_create :ensure_group_presence around_destroy :destroy_all_associates def feed ids = Array.new self.members.each do |member| ids += member.post_ids end Post.where("id IN (?)", ids) end def ensure_group_presence yield self.group_id.present? end def destroy_all_associates feed = self.feed yield feed.destroy_all end end 

您可以尝试在群组模型中使用此function。

 class Group < ActiveRecord::Base has_many :chatrooms , dependent: :destroy end 

现在,当你执行Group.last.destroy时 ,它应该删除以前的依赖关联聊天室,并且不会留下任何挂起的数据

您似乎正在尝试删除具有一个或多个聊天室的组。 由于您添加了外键约束( add_foreign_key "chatrooms", "groups" ),因此在分配了聊天室时不允许删除组。

要解决此问题,您必须在销毁组本身之前销毁所有关联的聊天室:

我认为这取决于您是否需要删除关联的表。 如果您需要删除关联的表,您应该

 has_many :chatrooms , dependent: :destroy 

但是,如果您不想删除关联的表,则应该

 has_many :chatrooms , dependent: :nullify 

rails API中有详细说明

 :dependent Controls what happens to the associated objects when their owner is destroyed. Note that these are implemented as callbacks, and Rails executes callbacks in order. Therefore, other similar callbacks may affect the :dependent behavior, and the :dependent behavior may affect other callbacks. :destroy causes all the associated objects to also be destroyed. :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not be executed). :nullify causes the foreign keys to be set to NULL. Callbacks are not executed. :restrict_with_exception causes an exception to be raised if there are any associated records. :restrict_with_error causes an error to be added to the owner if there are any associated objects. If using with the :through option, the association on the join model must be a belongs_to, and the records which get deleted are the join records, rather than the associated records. If using dependent: :destroy on a scoped association, only the scoped objects are destroyed. For example, if a Post model defines has_many :comments, -> { where published: true }, dependent: :destroy and destroy is called on a post, only published comments are destroyed. This means that any unpublished comments in the database would still contain a foreign key pointing to the now deleted post. 

RailsApi