Still having issues with Nested CrudRestControllers in TG 2.1.5

94 views
Skip to first unread message

ozwyzard

unread,
Apr 22, 2012, 6:11:57 AM4/22/12
to TurboGears
Configuration: Turbogears 2.1.5 CrudRestController, using _before()
calls in the nested controllers.

Issue: 'new' and 'delete' operations on last node of a set of nested
controllers land on the wrong nested controller

Scenario:
/controller1/arg1/controller2/controller3/new ends up calling /
controller1/arg1/controller2/new
controller1, controller2, controller3 all implement _before()

Untested: I've not tested the same for the 'edit' operation (since my
controllers do not implement the edit functionality for the particular
set of controllers in question).

Workaround: Seems to work if
restcontroller.py::RestDispatcher:_check_for_sub_controllers() is
modified to always execute the 'if var_args:' condition (e.g. changing
it to 'if 1:').

Alternative Workaround: Modify
restcontroller.py::RestDispatcher:_handle_get() to call
_handle_delete_edit_or_new() and _handle_custom_get() after the call
to self._is_controller(). With this fix, the 'new' (i.e. http get new
form) works, but the delete function would still not work.

Summary: The http method is tried against the first available item in
the remainder list, instead of being called against the last
controller in the remainder list.

Alessandro Molina

unread,
Apr 22, 2012, 6:46:00 AM4/22/12
to turbo...@googlegroups.com
Can you test if this is still true on 2.2 Beta?
2.2 switched to a new dispatch system (Crank) and it would be great to
know if the issue is still there in Crank.

> --
> You received this message because you are subscribed to the Google Groups "TurboGears" group.
> To post to this group, send email to turbo...@googlegroups.com.
> To unsubscribe from this group, send email to turbogears+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/turbogears?hl=en.
>

ozwyzard

unread,
Apr 22, 2012, 3:18:53 PM4/22/12
to TurboGears
I will try and test it on 2.2.

On Apr 22, 3:46 am, Alessandro Molina <alessandro.mol...@gmail.com>
wrote:

ozwyzard

unread,
Apr 22, 2012, 3:54:49 PM4/22/12
to TurboGears
Tested and found that the issue persists with 2.2 beta.
Crank 0.6.2 crank/restdispatcher.py:RestDispatcher class code is
similar to TG 2.1.5.

Alessandro Molina

unread,
Apr 23, 2012, 3:50:52 PM4/23/12
to turbo...@googlegroups.com
On Sun, Apr 22, 2012 at 12:11 PM, ozwyzard <ozwy...@gmail.com> wrote:
> Configuration:  Turbogears 2.1.5 CrudRestController, using _before()
> calls in the nested controllers.
>
> Issue: 'new' and 'delete' operations on last node of a set of nested
> controllers land on the wrong nested controller
>
> Scenario:
> /controller1/arg1/controller2/controller3/new ends up calling /
> controller1/arg1/controller2/new
> controller1, controller2, controller3 all implement _before()
>

Are controller1 and controller2 plain ObjectDispatch controllers or
are they rest controllers?

ozwyzard

unread,
Apr 23, 2012, 10:08:28 PM4/23/12
to TurboGears
All of the controllers are tg.ext.crud CrudRestControllers.

Additionally, probably unrelated, in the rest dispatch code that
checks
for subcontrollers, is their a possibility of a dangling
'else' (sorry
if i am asking too many questions).




On Apr 23, 12:50 pm, Alessandro Molina <alessandro.mol...@gmail.com>
wrote:

ozwyzard

unread,
Apr 23, 2012, 10:51:48 PM4/23/12
to turbo...@googlegroups.com

Here are some questions/comments as annotations in the existing code:

https://gist.github.com/2475710

Question: I am guessing that the dispatcher constructs the sequence of controllers (using add_controller())
on-demand as it traverses down the url_path, such that the controller lookup is done for each request.  Yes?
If so, the application can potentially dynamically add a new controller.  Yes?

Thanks.

Alessandro Molina

unread,
Apr 25, 2012, 7:16:34 PM4/25/12
to turbo...@googlegroups.com
On Tue, Apr 24, 2012 at 4:08 AM, ozwyzard <ozwy...@gmail.com> wrote:
> All of the controllers are tg.ext.crud CrudRestControllers.
>

I'm probably missing something.

I added a test unit on tg in test_rest_controller_dispatch (just copy
the test_var_sub_new_method and add one more controller in the middle)
to check for /controller1/arg1/controller2/controller3/new but it
seems that the dispatch code correctly serves controller3.new. This
makes me think that is not a dispatcher issue but a CrudRestController
one.

Can you provide a little app to show the issue? In that case I can
start working from that to check the issue and solve it

ozwyzard

unread,
Apr 26, 2012, 1:49:39 AM4/26/12
to turbo...@googlegroups.com

Thank you for looking into it.  It will take me a few days to write a sample app.  Hopefully sometime next week.  Hope that's okay.

ozwyzard

unread,
May 1, 2012, 3:48:09 AM5/1/12
to turbo...@googlegroups.com

I was able to reproduce the problem using a sample application.  I was able to narrow it down to one issue.  With that one change, the
nested CrudRestControllers work correctly in the sample app (as well as my app).  Without that change, it lands on the wrong
controller in the sample app.

I have placed the pertinent files here: https://bitbucket.org/wyzard/sample_tg215crud_app/

There are 3 controllers, 3 simple models, and associated __init__.py files, one call to the level1 controller in root.py, and
importing the model files in model/__init__.py

If the Level2Controller::get_one() method has a fixed argument, with no variable arguments, the level1/test/level2/level3/new routes to level2's new()
instead of level3's new().

If the Level2Controller::get_one() method takes dummy *arg and **kw args, the level3/new routes correctly to level3's new().

I have many print statements in my copy of the TG 2.1.5 code-base to track this, which I have not included in the sample app repository.

When the level2 get_one() takes variable args (ArgSpec), the _check_for_sub_controllers() routine takes the "if var_args:' path,
else it takes the 'elif:' path.

Is there a requirement that the get_one() method of nested CrudRestControllers should take variable arguments?  Am I using it incorrectly?

In essence, either I am using it incorrectly, or there is some defect in the ELIF case.

If you would like me to add other files, let me know.

Thank you for your time and effort.

wyzard

ozwyzard

unread,
Jun 10, 2012, 9:06:57 PM6/10/12
to turbo...@googlegroups.com

Did the sample application help narrow down the issue?  Let me know if I am mistaken.

Thanks.

Alessandro Molina

unread,
Jun 12, 2012, 4:39:44 PM6/12/12
to turbo...@googlegroups.com
I tried replicating the issue in a test to include it inside the TG
test suite, but have been unable to.

This is the test that I added to the test unit following your
guidelines, but it seems to correctly get dispatched to third/new and
not to the wrong controller as in your case:
https://gist.github.com/2919976

Let me know if that code replicates the issue for you.
> --
> You received this message because you are subscribed to the Google Groups
> "TurboGears" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/turbogears/-/kW9yadsE7ekJ.

ozwyzard

unread,
Jun 16, 2012, 5:14:14 AM6/16/12
to turbo...@googlegroups.com
Thanks for the test unit.  I included it in a sample app, it works as expected.  I.E., the test unit does not
reproduce the problem I have seen with CrudRestController sample app.  I will try and get back to you in
a week comparing the test unit versus sample app and check if it executes the appropriate line of code
in the dispatcher.



On Tuesday, June 12, 2012 1:39:44 PM UTC-7, Alessandro Molina wrote:
I tried replicating the issue in a test to include it inside the TG
test suite, but have been unable to.

This is the test that I added to the test unit following your
guidelines, but it seems to correctly get dispatched to third/new and
not to the wrong controller as in your case:
https://gist.github.com/2919976

Let me know if that code replicates the issue for you.

Reply all
Reply to author
Forward
0 new messages