Search code examples
ruby-on-railsruby-on-rails-5self-referencing-table

Model callbacks not working with self referential association


I am having a model Evaluation that has many sub evaluations (self refential)

class Evaluation < ApplicationRecord

  has_many :sub_evaluations, class_name: "Evaluation", foreign_key: "parent_id", dependent: :destroy

  before_save :calculate_score

  def calculate_score
    # do something
  end

end

I am creating and updating evaluation with sub evaluations as nested attributes.

calculate_score method is triggered on sub evaluation creation but not while updating. I have tried before_update and after_validation. But nothing seems to be working.

Evaluation form

= form_for @evaluation do |f|
  ...
  = f.fields_for :sub_evaluations do |sub_evaluation|
   ...

What seems to be the issue?


Solution

  • This article helped me to fix the issue.

    Child callback isn't triggered because the parent isn't "dirty".

    The solution in the article is to "force" it to be dirty by calling attr_name_will_change! on a parent attribute that, in fact, does not change.

    Here is the updated model code:

    class Evaluation < ApplicationRecord
    
      has_many :sub_evaluations, class_name: "Evaluation", foreign_key: "parent_id", dependent: :destroy
    
      before_save :calculate_score
    
      def calculate_score
        # do something
      end
    
      def exam_id= val
        exam_id_will_change!
        @exam_id = val
      end
    
    end
    

    See Active Model Dirty in the Rails API