[Grok-dev] indexes not getting updated for contents added via ApplicationInitializedEvent subscriber

Joshua Immanuel josh at hipro.co.in
Tue Nov 27 18:46:19 UTC 2012

Hello list,

On Mon, 2012-11-26 at 14:59 +0530, Joshua Immanuel wrote:
> This is how my subscriber looks like
>         @grok.subscribe(IMyRoot, grok.ApplicationInitializedEvent)
>         def cbAppRootAdded(app_root, event):
>             catalog = component.queryUtility(ICatalog,
> context=app_root)
>             # catalog is not None
>             intids = component.queryUtility(
>                 IIntIds, context=app_root, default=None)
>             # intids is also not None
>             my_folder = MyFolder() # grok.Container object
>             my_default_object = MyObject(...) # grok.Model object
>             grok.notify(grok.ObjectCreatedEvent(my_default_object))
>             my_folder['default_object'] = my_default_object
>             app_root['my_folder'] = my_folder
>             transaction.commit()
> I even tried adding the default object via IObjectAddedEvent
> subscriber for IMyFolder. Still, the indexes for MyObject were not
> getting updated.

I spoke to @trollfot in IRC channel, he was very patient and kind to
answer my queries. This is the abstract of the talk. Please correct it,
if I am wrong or if I have missed anything.

Inside the subscriber of ApplicationInitializedEvent we can count on the
fact that the local utilities such as Catalog and IntIds will be
registered. As we know that the utilities are looked up in site manager,
so during a traversal the registry lookups will be set to application
root's ('MyRoot' as per the above example code) site manager. But,
ApplicationInitializedEvent is triggered by Grok Admin, as our
application is not yet traversed at that time, the current site manager
at that point will be the global site manager. So, we won't be getting
the local utilities registers for our IMyRoot. Thereby our indexes
registered will not get updated if we add the object at that time.

We need to instruct Grok to use the local site manager of our
application root for lookups inside our subscriber code. Since IntIds
requires that the object should be persisted in order to generate int
ids. We need to add the 'my_folder' to app_root then add MyObject to it.
So our modified code will look like this

        from zope.component.hooks import setSite, getSite
        @grok.subscribe(IKalam, grok.ApplicationInitializedEvent)
        def cbAppRootAdded(app_root, event):
            previous_sm = getSite()
            # Instruct Grok to use our app_root's local site manager
            my_folder = MyFolder() # grok.Container object
            # First persist the container object
            app_root['my_folder'] = user_folder
            my_default_object = MyObject(...) # grok.Model object
            # Persist our object so that IntIds can be generated
            my_folder['default_object'] = my_default_object
            # restore back to original site manager
The above code works perfectly. I would like to thank @trollfot for his
time and help.
Joshua Immanuel
HiPro IT Solutions Private Limited
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://mail.zope.org/pipermail/grok-dev/attachments/20121128/7ab1efdf/attachment.sig>

More information about the Grok-dev mailing list