Error that need to be solved:
ActiveRecord::StatementInvalid: Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (
slap_chat_development.chatrooms, CONSTRAINTfk_rails_496733c195FOREIGN KEY (group_id) REFERENCESgroups(id)): DELETE FROMgroupsWHEREgroups.id= 1
QUESTION IS:
As I see problem persists in relation between groups and chatrooms tables.
Further details:
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
Group model:
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
Chatroom model:
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
                You can try using this in your group model.
class Group < ActiveRecord::Base
  has_many :chatrooms , dependent: :destroy
end
Now when you execute, Group.last.destroy, it should delete the dependent associated chatrooms before and no hanging data would be left
It seems like you are trying to delete a group that has one or many chatrooms.
But because you added a foreign key constraint (add_foreign_key "chatrooms", "groups"), it is not allowed to delete a group when there is still a chatroom assigned.
To solve this issue you have to destroy all associated chatrooms before destroying the group itself.
I think it depends on whether you need to delete the associated table. If you need to delete the associated table, you should
has_many :chatrooms , dependent: :destroy
However, if you do not want to delete the associated table, you should
has_many :chatrooms , dependent: :nullify
There are detailed descriptions in the 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With