Odd behavior in Mongoid: after_add callback launched when accessing the reference model

The model callback is launched after accessing the reference document. This is a weird behavior, and I'm not sure why this is happening.

Here is an example of reproducibility:

class Group
    include Mongoid::Document
    include Mongoid::Timestamps

    belongs_to :domain_group, :class_name => 'Domain', :inverse_of => :child_groups

    field :name
end

class Domain < Group

    has_many :child_groups, :class_name => 'Group', :inverse_of => :domain_group, after_add: :print_childgroup

    field :sid

    def print_childgroup(group)
        puts 'calling print_childgroup()'
    end
end

Route Processing:

get "/temp_init" do
    d = Domain.create(name: 'Domain', sid: '23Asdfai9')
    Group.create(name: 'group1', domain_group: d)
    Group.create(name: 'group2', domain_group: d)
end

get "/view" do
    g = Group.where(name: 'group1').first
    d = g.domain_group
end

To see it in action:

  • Visit /temp_initto create initial values ​​and show the console:

    calling print_childgroup()
    calling print_childgroup()
    

    This is expected since we just added two groups, so the callback after_addstarts twice.

  • Visit /viewand the console output will display:

    calling print_childgroup()
    

    It is NOT expected

    The insult string g.domain_group, for some reason, calls a callback after_add.

My current workaround is this:

# Grab the domain group id
d_id = g.domain_group_id

d = Domain.find(d_id)
# Do stuff with d object

, , . g.domain_group add ?

+4

All Articles