Days ago I was working on a problem with the new instances returned by methods that call related elements in models in this publication
I have found a simple way to solve this problem by implementing a simple interface in the classes of models that we want to reuse globally in our applications
namespace Phalcon\Mvc\Model;
interface ReusableInterface {
public function getUniqueKey();
}
if reusable {
if referencedModel instanceof ReusableInterface {
let uniqueKey = referencedModel->getUniqueKey();
} else {
let uniqueKey = unique_key(referencedModel, arguments);
}
let records = this->getReusableRecords(referencedModel, uniqueKey);
if typeof records == "array" || typeof records == "object" {
return records;
}
}
class Invoice extends \Phalcon\Mvc\Model implements \Phalcon\Mvc\Model\ReusableInterface {
const COL_ID = 'id';
const COL_DATE = 'date';
const REL_ITEMS = 'relItems';
private $id;
private $date;
public function initialize() {
$this->setSource('invoices');
$this->hasMany(
self::COL_ID,
Item::class,
Item::COL_INVOICE_ID,
[
'alias' => self::REL_ITEMS,
'reusable' => true,
]
);
}
public function getUniqueKey() {
return __CLASS__ . ':' . self::COL_ID . ':' . $this->getId();
}
public function getItems(): Simple
{
return $this->{self::REL_ITEMS};
}
public function setItems(array $items = []) : self
{
$this->{self::REL_ITEMS} = $items;
return $this;
}
// setters getters
}
class Item extends \Phalcon\Mvc\Model implements \Phalcon\Mvc\Model\ReusableInterface {
const COL_ID = 'id';
const COL_NAME = 'name';
const COL_PRICE = 'price';
const COL_INVOICE_ID = 'invoiceId';
const REL_INVOICE = 'relInvoice';
private $id;
private $name;
private $price;
private $invoiceId;
public function initialize() {
$this->setSource('invoices_items');
$this->belongsTo(
self::COL_INVOICE_ID,
Invoice::class,
Invoice::COL_ID,
[
'alias' => self::REL_INVOICE,
'foreignKey' => [
'allowNulls' => false,
'message' => 'Hey! where is my invoice?',
],
'reusable' => true,
]
);
}
public function getUniqueKey() {
return __CLASS__ . ':' . self::COL_ID . ':' . $this->getId();
}
public function getInvoice(): ?Invoice
{
return $this->{self::REL_INVOICE} ?: null;
}
public function setInvoice(Invoice $invoice) : self
{
$this->{self::REL_INVOICE} = $invoice;
return $this;
}
// setters getters
}
// After
$invoice = (new Invoice())->findFirst(1234);
var_dump(spl_object_hash($invoice)); // 00000000546e8820000000005fdc6415
var_dump(spl_object_hash($invoice->getItems()->getFirst()->getInvoice())); // 00000000546efff0000000005fdc6415
// Before
$invoice = (new Invoice())->findFirst(1234);
var_dump(spl_object_hash($invoice)); // 00000000546e8820000000005fdc6415
var_dump(spl_object_hash($invoice->getItems()->getFirst()->getInvoice())); // 00000000546e8820000000005fdc6415
Well I hope your comments on the matter. I hope I have been explicit enough in my idea