ckeat9
ckeat9

Reputation: 162

Rails: how to run model callback after update its nested attributes?

i was trying to do a callback for a model after updating a nested attribute. during the callback, i was unable to access the newly created nested attribute id. some example below:

Models:

class OptionType < ActiveRecord::Base 

    has_many :option_values
    accepts_nested_attributes_for :option_values
    after_update :print_new_option_value

    def print_new_option_value

        @option_value = []

        option_values.each do |option_value|
            if option_value.new_record?
                @option_value << option_value
            end
        end

        @option_value.each do |ov|
            print "This is the new option_value name = #{ov.name}"
            print "This the new option_value id = #{ov.id}"
        end
    end
end

class OptionValue < ActiveRecord::Base
    belongs_to :option_type
end

after i update the option type with a new option value (name: new option value), the following rails log appear:

enter image description here

  1. the message can display the nested attribute name inputted after updating the option type
  2. but the nested attribute id is empty
  3. turns out the nested attribute is updated after option type callback.

my question, how can i update the nested attribute (option value) before calling the option type callback? reason being, i need to access the nested attribute id for some codes.

thanks and appreciated greatly.

Upvotes: 1

Views: 1344

Answers (1)

Slava.K
Slava.K

Reputation: 3080

You may also approach this problem from another side - add after_create callback to OptionValue model that will notify OptionType:

class OptionType < ActiveRecord::Base
    has_many :option_values
    accepts_nested_attributes_for :option_values

    def print_new_option_value(new_option)
       print "This is the new option_value name = #{ov.name}"
       print "This the new option_value id = #{ov.id}"
    end
end

class OptionValue < ActiveRecord::Base
    belongs_to :option_type
    after_create :notify_option_type

    def notify_option_type
      option_type.print_new_option_value(self)
    end
end

Upvotes: 1

Related Questions