Issue removing ParseObject from ParseRelation
jschwartzmtn opened this issue · 12 comments
In the code below, I have an array of objectId's from my _User class ($_POST["crew"]). After getting the relation I query the relation to check for these users, and if those users are in the PFRelation, I remove them.
For some reason when I do this I'm getting an uncaught internal server error on Parse Server. If I comment out the lines where remove() is called, I don't get the exception. If I run this with all of the code live, no errors are thrown by ParseException, but the users are not removed. Is this something I am doing wrong? It seems pretty straight forward, but I can't get it working.
if (isset($_POST["submit"]) && isset($_POST["jobId"]) && isset($_POST["crew"])) {
try {
$query = new ParseQuery("Job");
$query->includeKey("unsignedCrew");
$query->includeKey("signedCrew");
$job = $query->get($_POST['jobId']);
$unsignedCrewRelation = $job->getRelation("unsignedCrew", "_User");
$unsignedQuery = $unsignedCrewRelation->getQuery();
$unsignedQuery->containedIn("objectId", $_POST["crew"]);
$unsignedCrewToRemove = $unsignedQuery->find();
if (count($unsignedCrewToRemove) > 0) {
$unsignedCrewRelation->remove($unsignedCrewToRemove);
}
$signedCrewRelation = $job->getRelation("signedCrew");
$signedQuery = $signedCrewRelation->getQuery();
$signedQuery->containedIn("objectId", $_POST["crew"]);
$signedCrewToRemove = $signedQuery->find();
if (count($signedCrewToRemove) > 0) {
$signedCrewRelation->remove($signedCrewToRemove);
}
$job->save();
$errors = array();
$successString = "Crew members removed successfully!";
header('location:view.php?success=' . $successString);
}
catch (ParseException $error) {
header('location:view.php?exception=' . $error->getMessage());
}
}It's also worth mentioning, that in the course of troubleshooting this, I've done a var_dump on every variable I created and all come back as expected.
Can you write a failing test? I believe this could all be done simpler without the unnecessary querying. Also your doing includeKey on a relation. IncludeKey is for pointers.
Right you are, I added the includeKey after running out of good ideas and hoping there was something missing from the documentation.
How would I go about removing objects without querying? It is my understanding that with relations, you have to add and remove ParseObjects, it is not enough to just have their objectIds. Am I wrong in that?
Fork the project, create a branch and write a test here then we both can look into it.
If you need help running test refer to the CONTRIBUTING.md
Unfortunately I don't have the time to get into that at the moment - this is setup on a hosted Parse Server that I don't have access to alter configuration for, so migrating it would be a process. I refactored my code a little and using this function, I have the same issue (as expected, since I really didn't change the process at all, just made it cleaner):
function removeRelation(ParseObject $parent, string $field, array $objectIds) {
$relation = $parent->getRelation($field, '_User');
$query = $relation->getQuery();
$query->containedIn('objectId', $objectIds);
$objectsToRemove = $query->find();
if (!empty($objectsToRemove)) {
$relation->remove($objectsToRemove);
}
}
Are objects getting returned when you do your query?
function removeRelation(ParseObject $parent, string $field, array $objectIds) {
$relation = $parent->getRelation($field, '_User'); <------ Second parameter is optional.
$query = $relation->getQuery();
$query->containedIn('objectId', $objectIds);
$objectsToRemove = $query->find(); <-------------- HERE
if (!empty($objectsToRemove)) {
$relation->remove($objectsToRemove);
}
}
Yes, if I do
echo var_dump($objectsToRemove);
I get an array of ParseObjects. The results are as expected, an array of the objects in the relation that are also in $objectIds. I have also tried it with and without specifying the class in getRelation(), same result both ways.
@jschwartzmtn I added a test #440 It passes locally for me. Compare it to what you have been doing, or change the test
Thanks, that does look to test exactly what I am doing. Perhaps there is an issue with my hosted server, I will address this with the hosting company. Thank you for all your help!
I'm getting an uncaught internal server error on Parse Server.
Can you post logs? VERBOSE=1
2019-04-10T15:00:26.908Z - Uncaught internal server error.
2019-04-10T15:00:26.907Z - Error generating response. TypeError: Cannot read property 'className' of undefined
at getObjectType (/usr/src/app/node_modules/parse-server/lib/Controllers/SchemaController.js:1056:38)
at getObjectType (/usr/src/app/node_modules/parse-server/lib/Controllers/SchemaController.js:1059:16)
at getType (/usr/src/app/node_modules/parse-server/lib/Controllers/SchemaController.js:977:14)
at SchemaController.validateObject (/usr/src/app/node_modules/parse-server/lib/Controllers/SchemaController.js:783:24)
at loadSchema.then.then (/usr/src/app/node_modules/parse-server/lib/Controllers/DatabaseController.js:384:21)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
Nevermind, I think I finally tracked it down to a mismatch in the version of Parse Server and the SDK I was using. I updated both to the latest version and it is working now. Thanks again for your help, I knew it was something silly!
Glad you got it working!