Search code examples
ruby-on-railsruby-on-rails-5rails-activerecord

delete belongs_to instance if no instances of has_many exist


For these models:

class Folder < ApplicationRecord
   has_many :documents_folders_requests, dependent::destroy 
end

class DocumentsFoldersRequest < ApplicationRecord
  belongs_to :folder
  belongs_to :child_folder, class_name: "Folder", optional: true
end

If a DocumentsFoldersRequest record is deleted, and no other documents_folders_request record exists which uses that Folder record for either the folder_id or the child_folder_id, is there a way to automatically delete the Folder record? It would be considered "orphaned" at this point - since it is not found on any association, and there's no folders_controller#index to display all the folder records anywhere. Can this be done from the model?

example:

dfr = DocumentsFoldersRequest.find_by(document_id: 123)

folder_id = dfr.folder.id 
=> [1]

dfr.destroy_all
=> true

# is there a better way to write the following: 
if DocumentsFoldersRequest.where(folder: folder_id).nil? && DocumentsFoldersRequest.where(child_folder: folder_id).nil?
  folder = Folder.find(folder_id)
  folder.destroy
end 

Solution

  • There are a few options. Mostly it comes down to when you want to do this.

    I'd suggest you do it when deleting a DocumentsFoldersRequest

    Any time you delete one, check the parent folder and child_folder:

    class DocumentsFoldersRequest < ApplicationRecord
      after_destroy :check_for_orphaned_folder
    
      def check_for_orphaned_folder
        folder.destroy if folder.documents_folders_requests.none?
        child_folder.destroy if child_folder.documents_folders_requests.none?
      end
    
    end