vanstyn / RapidApp

Turnkey ajaxy webapps
http://rapi.io
Other
48 stars 15 forks source link

Recursive requests from `redirect_handle_rest_rel_request()` are broken for self-referential relationships #201

Closed deven closed 2 years ago

deven commented 2 years ago

Given a self-referential relationship like this for MyApp::Schema::Result::Customer:

__PACKAGE__->has_many(
  "child_customers",
  "MyApp::Schema::Result::Customer",
  { 'foreign.parent_customer_id' => 'self.id' },
  { cascade_copy => 0, cascade_delete => 0 },
);

With this self-referential relationship, a URI path like /main/db/db_customer/item/1234/rel/child_customers is broken. Instead of returning the matching customer records, this will return all customers.

After extensive tracing and debugging of the core RapidApp code, and discussing this issue with @vanstyn, I believe I have a fix for the root cause of the bug. The chain of causation (in reverse) looks like this:

The recursive call from redirect_handle_rest_rel_request() to $c->root_module_controller->approot($c,$url) is meant to run as an independent request with fresh object state, so the recursive call should not be skipping ONREQUEST handlers which previously ran for the original request. While it took many hours to trace/debug the code and understand the chain of causation above, the actual code fix is very simple. The value of $c->request_id must be changed to a unique value during the recursive approot() call, which can be accomplished with a single-line code change for each of the two recursive approot() calls. This will cause RapidApp to actually treat the recursive request as an independent request and run all ONREQUEST handlers as it should, regardless of what ONREQUEST handlers may have already run during the original request.

With this fix, the self-referential relationship URL works correctly, returning the intended subset of customers in the results.

This is the same technique used by RapidApp::RapidApp::cleanupAfterRequest() for any post-processing tasks that it runs. My patch adds 0.01 to the $c->request_id value to prevent overlap with the values generated for post-processing tasks.

vanstyn commented 2 years ago

Fixed in PR #202