55namespace Michalsn \CodeIgniterNestedModel \Traits ;
66
77use CodeIgniter \Autoloader \FileLocatorInterface ;
8+ use CodeIgniter \Model ;
89use Michalsn \CodeIgniterNestedModel \Enums \RelationTypes ;
910
1011trait HasLazyRelations
@@ -14,35 +15,34 @@ trait HasLazyRelations
1415 */
1516 private array $ handledRelations = [];
1617
18+ private ?Model $ relationModel = null ;
19+ private bool $ relationModelResolved = false ;
20+
1721 public function __get (string $ key )
1822 {
19- $ result = parent ::__get ($ key );
23+ if (array_key_exists ($ key , $ this ->attributes )) {
24+ return parent ::__get ($ key );
25+ }
26+
27+ $ model = $ this ->getRelationModel ();
2028
21- if ($ result === null && ! isset ($ this ->handledRelations [$ key ])) {
22- $ result = $ this ->handleRelation ($ key );
23- $ this ->handledRelations [$ key ] = true ;
29+ if ($ model !== null && method_exists ($ model , $ key )) {
30+ if (! isset ($ this ->handledRelations [$ key ]) && ! array_key_exists ($ key , $ this ->attributes )) {
31+ $ this ->handleRelation ($ key , $ model );
32+ $ this ->handledRelations [$ key ] = true ;
33+ }
34+
35+ return $ this ->attributes [$ key ] ?? null ;
2436 }
2537
26- return $ result ;
38+ return parent :: __get ( $ key ) ;
2739 }
2840
2941 /**
3042 * Load relation for the property.
3143 */
32- private function handleRelation (string $ name )
44+ private function handleRelation (string $ name, Model $ model )
3345 {
34- $ className = $ this ->findModelClass ();
35-
36- if ($ className === null ) {
37- return null ;
38- }
39-
40- $ model = model ($ className );
41-
42- if (! method_exists ($ model , $ name )) {
43- return null ;
44- }
45-
4646 $ relation = $ model ->{$ name }();
4747
4848 if (in_array ($ relation ->type , [RelationTypes::hasOne, RelationTypes::belongsTo], true )) {
@@ -65,6 +65,23 @@ private function handleRelation(string $name)
6565 return $ this ->attributes [$ name ];
6666 }
6767
68+ /**
69+ * Resolve the matching model once for the lifetime of the entity instance.
70+ */
71+ private function getRelationModel (): ?Model
72+ {
73+ if ($ this ->relationModelResolved ) {
74+ return $ this ->relationModel ;
75+ }
76+
77+ $ className = $ this ->findModelClass ();
78+
79+ $ this ->relationModel = $ className === null ? null : model ($ className );
80+ $ this ->relationModelResolved = true ;
81+
82+ return $ this ->relationModel ;
83+ }
84+
6885 /**
6986 * Search for the proper model.
7087 *
0 commit comments