You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 relationship URL displays all customers instead of the correct list of specific customers.
This is because the Ajax request to /main/db/db_customer/store/read sends POST parameters which are missing the rs_method and rs_path parameters, which are required to narrow the result set to the correct results.
This is because the Ajax request to the relationship URI returns Javascript code without base parameters containing the rs_method and rs_path parameters.
This is because redirect_handle_rest_rel_request() uses the ExtJS configuration data in the RapidApp::Module::DatStor store object to construct the base parameters, and the rs_method and rs_path are also missing from the store object's ExtJS configuration.
This is because store_init_onrequest() sets the ExtJS configuration, but it doesn't have the rs_method and rs_path values available when it runs on the store object.
This is because store_init_onrequest() runs on the store object beforeredirect_handle_rest_rel_request() runs, determining the correct rs_method and rs_path values.
This is because the store_init_onrequest() method runs as an ONREQUEST handler, which only run once per request. In this case, the ONREQUEST handlers for the store object have already been triggered earlier in the relationship URI request cycle by the time redirect_handle_rest_rel_request() runs.
This only seems to be an issue for self-referential relationships. If the relationship connects to different table, redirect_handle_rest_rel_request() ends up running before the ONREQUEST handlers for the other table's store object, which is why the relationship URLs normally work as expected.
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.
The text was updated successfully, but these errors were encountered:
deven
added a commit
to deven/RapidApp
that referenced
this issue
Nov 18, 2021
Use "local" to bypass the attribute accessor and dynamically override
the internal $c->{request_id} field during recursive approot() calls,
adding 0.01 to the value to avoid overlap with similar values generated
by RapidApp::RapidApp::cleanupAfterRequest() for post-processing tasks.
deven
added a commit
to deven/RapidApp
that referenced
this issue
Nov 18, 2021
Use "local" to bypass the attribute accessor and dynamically override
the internal $c->{request_id} field during recursive approot() calls,
adding 0.01 to the value to avoid overlap with similar values generated
by RapidApp::RapidApp::cleanupAfterRequest() for post-processing tasks.
Given a self-referential relationship like this for
MyApp::Schema::Result::Customer
: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:
/main/db/db_customer/store/read
sends POST parameters which are missing thers_method
andrs_path
parameters, which are required to narrow the result set to the correct results.rs_method
andrs_path
parameters.redirect_handle_rest_rel_request()
uses the ExtJS configuration data in theRapidApp::Module::DatStor
store object to construct the base parameters, and thers_method
andrs_path
are also missing from the store object's ExtJS configuration.store_init_onrequest()
sets the ExtJS configuration, but it doesn't have thers_method
andrs_path
values available when it runs on the store object.store_init_onrequest()
runs on the store object beforeredirect_handle_rest_rel_request()
runs, determining the correctrs_method
andrs_path
values.store_init_onrequest()
method runs as an ONREQUEST handler, which only run once per request. In this case, the ONREQUEST handlers for the store object have already been triggered earlier in the relationship URI request cycle by the timeredirect_handle_rest_rel_request()
runs.redirect_handle_rest_rel_request()
ends up running before the ONREQUEST handlers for the other table's store object, which is why the relationship URLs normally work as expected.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 recursiveapproot()
call, which can be accomplished with a single-line code change for each of the two recursiveapproot()
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.The text was updated successfully, but these errors were encountered: