ruby-on-railsrubycallbackredminedestroy

Redmine (RoR)- Accessing IssueRelation during issue destruction


My goal is to propagate the deletion of an issue to change a custom field of the linked issue. So, I intercept the destruction of an issue.

I'm encountering a problem in my redmine plugin. IssueRelation are not accessible as expected when calling the before_destroy hook in issue model.

Context :
Redmine version                5.0.5.devel and 5.1.2.stable
Ruby version                   2.7.4-p191 (2021-07-07) [x86_64-linux-gnu] / 3.2.4-p170 (2024-04-23) [x86_64-linux]
Rails version                  6.1.7.4

what I mean is that for the same function. for example Rails.logger.info(IssueRelation.where(issue_from: self.id).inspect).

if I run it with the after_save, before_save hook and some relationships exist I'll see them but when I'm in a before_destroy or after_destroy hook the result of IssueRelation.where(issue_from: self.id).inspect is empty

Here is an exemple:

module RedmineMyPlugin
  module Patches
    module IssuePatch
      extend ActiveSupport::Concern

      included do

        prepend InstanceOverwriteMethods
        include InstanceMethods

        # TEST
        # has_many :issue_relations_from, class_name: 'IssueRelation', foreign_key: 'issue_from_id', dependent: :destroy
        # has_many :issue_relations_to, class_name: 'IssueRelation', foreign_key: 'issue_to_id', dependent: :destroy
        # before_destroy :notify_related_issues, if: :is_tracker_diag?
        # before_save :notify_related_issues, if: :is_tracker_diag?
        # after_destroy :notify_related_issues, if: :is_tracker_diag?
        around_destroy :notify_related_issues, if: :is_tracker_diag?


      end

      def self.apply_patch
        Issue.send(:include, RedmineTapao::Patches::IssuePatch)
      end

      module InstanceOverwriteMethods
        # Ajoutez ici toute méthode que vous souhaitez surcharger
      end

      module InstanceMethods

        def notify_related_issues
          Rails.logger.info(IssueRelation.all.inspect)
          Rails.logger.info(IssueRelation.where(issue_from: self.id).inspect)
          Rails.logger.info(IssueRelation.where(issue_to: self.id).inspect)
          Rails.logger.info(self.relations.inspect)
        end


      end # InstanceMethods

    end # IssuePatch
  end # Patches
end # RedmineMyPlugin

I also tried in the IssueRelation model; however, when an Issue is destroyed, it seems that it does not pass through IssueRelation#destroy to remove the relation from the database.

Is this a known and unsolvable problem due to the framework’s architecture, or am I just handling it very poorly?

Thank you in advance for your help.


Solution

  • The issue_relations seem to be deleted before your before_destroy callback is executed.

    According to the Rails documentation here:

    before_destroy callbacks should be placed before dependent: :destroy associations (or use the prepend: true option) to ensure they execute before the records are deleted by dependent: :destroy.

    To ensure your before_destroy callback runs before any other, you can add "prepend: true" to it :

    before_destroy :notify_related_issues, prepend: true