We have a database model that looks like this:
CREATE TABLE `Recipient` (
`username` VARCHAR(15),
`full_name` VARCHAR(45) NOT NULL,
`email` VARCHAR(50) NOT NULL,
`phone` VARCHAR(20) NOT NULL,
`status` BIT NOT NULL,
PRIMARY KEY (`username`)
) DEFAULT CHARSET=utf8;
CREATE TABLE `Printer` (
`id` INT(6) UNSIGNED AUTO_INCREMENT,
`arrival_date` DATETIME NOT NULL,
`archived_date` DATETIME,
`recipient_id` VARCHAR(15) NOT NULL,
FOREIGN KEY(`recipient_id`) REFERENCES Recipient(`username`),
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE `Owner` (
`id` INT(6) UNSIGNED AUTO_INCREMENT,
`name` VARCHAR(30) UNIQUE NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE `Document` (
`serial` VARCHAR(50),
`picture` TEXT,
`owner_id` int(6) UNSIGNED NOT NULL,
`printer_id` INT(6) UNSIGNED,
FOREIGN KEY(`owner_id`) REFERENCES Owner(`id`),
FOREIGN KEY(`printer_id`) REFERENCES Printer(`id`),
PRIMARY KEY(`serial`)
) DEFAULT CHARSET=utf8;
When we call our method get_printers
, which looks like this:
public function get_printers(){
$printers = \PrinterQuery::create()
->joinWith("Document")
->useDocumentQuery()
->joinWith("Owner")
->endUse()
->joinWith("Recipient")
->find();
return $printers->toJSON();
}
we get this as response
{
"Printers": [
{
"Id": 1,
"ArrivalDate": null,
"ArchivedDate": null,
"RecipientId": "myusername",
"Recipient": {
"Username": "myusername",
"FullName": "Sture Testsson",
"Email": "email@example.com",
"Phone": "07383918",
"Status": "\u0001",
"Printers": [
"*RECURSION*"
]
},
"Documents": [
{
"Serial": "111",
"Picture": "url",
"OwnerId": 1,
"PrinterId": 1,
"Printer": "*RECURSION*"
},
{
"Serial": "222",
"Picture": null,
"OwnerId": 2,
"PrinterId": 1,
"Printer": "*RECURSION*"
},
{
"Serial": "333",
"Picture": null,
"OwnerId": 3,
"PrinterId": 1,
"Printer": "*RECURSION*"
}
]
}
]
}
Question:
What causes the "Printer": "*RECURSION*"
to happen, and how can we remove it from the response? Preferably without having to SELECT
each and every column except the "remote" foreign keys.
So it seems like toJSON()
creates a JSON representation of the whole Collection
(including its metadata), which contain objects that allows for moving both up and down in the object hierarchy, i.e Printer
holds a reference to Document
which in turn holds a reference back to its parent - Printer
. A nifty little feature once you get a hold of how it should be done.
The solution in this case was to add a Formatter
, as suggested here.
The end result looks like this:
$printers = \PrinterQuery::create()
->joinWith("Document")
->useDocumentQuery()
->joinWith("Owner")
->endUse()
->joinWith("Recipient")
->setFormatter('\Propel\Runtime\Formatter\ArrayFormatter')
->find();
return $printers->toJSON();
}