@@ -27,6 +27,8 @@ class Record implements \ArrayAccess
27
27
/** @var Record[][] */
28
28
private $ references ;
29
29
30
+ private $ model ;
31
+
30
32
public function __construct (Schema $ schema )
31
33
{
32
34
$ this ->schema = $ schema ;
@@ -79,37 +81,41 @@ public function getSchema(): Schema
79
81
80
82
public function getModel (): Model
81
83
{
82
- return $ this ->schema ->getModel ($ this );
84
+ if ($ this ->model === null ) {
85
+ $ this ->model = $ this ->schema ->getModel ($ this );
86
+ }
87
+
88
+ return $ this ->model ;
83
89
}
84
90
85
- public function getReferredModel (string $ name ): Model
91
+ public function getReferencedModel (string $ name ): Model
86
92
{
87
- $ reference = $ this ->getSchema ()->getReference ($ name );
93
+ $ relationship = $ this ->getSchema ()->getRelationship ($ name );
88
94
89
- if (!$ reference -> isSingleRelationship ()) {
90
- throw new \RuntimeException ('Can only refer to single models in a single relationship ' );
95
+ if (!$ relationship -> isUniqueRelationship ()) {
96
+ throw new \RuntimeException ('Cannot fetch a single model a non-unique relationship ' );
91
97
}
92
98
93
- $ records = $ this ->getReference ($ name );
99
+ $ records = $ this ->getReferencedRecords ($ name );
94
100
95
101
if (empty ($ records )) {
96
- throw new \ UnexpectedValueException ( ' The single relationship does not refer to any record ' ) ;
102
+ return null ;
97
103
}
98
104
99
- return $ records [0 ]->getModel ();
105
+ return $ this -> getReferencedRecords ( $ name ) [0 ]->getModel ();
100
106
}
101
107
102
108
public function getReferredModels (string $ name ): array
103
109
{
104
- $ reference = $ this ->getSchema ()->getReference ($ name );
110
+ $ reference = $ this ->getSchema ()->getRelationship ($ name );
105
111
106
- if ($ reference ->isSingleRelationship ()) {
112
+ if ($ reference ->isUniqueRelationship ()) {
107
113
throw new \RuntimeException ('Cannot refer to multiple models in a single relationship ' );
108
114
}
109
115
110
116
$ models = [];
111
117
112
- foreach ($ this ->getReference ($ name ) as $ record ) {
118
+ foreach ($ this ->getReferencedRecords ($ name ) as $ record ) {
113
119
$ models [] = $ record ->getModel ();
114
120
}
115
121
@@ -118,21 +124,21 @@ public function getReferredModels(string $name): array
118
124
119
125
public function getReferredProxyModels (string $ proxy , string $ name ): array
120
126
{
121
- $ proxyReference = $ this ->getSchema ()->getReference ($ proxy );
122
- $ reference = $ proxyReference ->getReferencedSchema ()->getReference ($ name );
127
+ $ proxyReference = $ this ->getSchema ()->getRelationship ($ proxy );
128
+ $ reference = $ proxyReference ->getReferencedSchema ()->getRelationship ($ name );
123
129
124
- if ($ proxyReference ->isSingleRelationship ()) {
130
+ if ($ proxyReference ->isUniqueRelationship ()) {
125
131
throw new \RuntimeException ('Cannot refer to multiple models in a single relationship ' );
126
132
}
127
133
128
- if (!$ reference ->isSingleRelationship ()) {
134
+ if (!$ reference ->isUniqueRelationship ()) {
129
135
throw new \RuntimeException ('Can only refer to single models in a single relationship ' );
130
136
}
131
137
132
138
$ models = [];
133
139
134
- foreach ($ this ->getReference ($ proxy ) as $ record ) {
135
- $ records = $ record ->getReference ($ name );
140
+ foreach ($ this ->getReferencedRecords ($ proxy ) as $ record ) {
141
+ $ records = $ record ->getReferencedRecords ($ name );
136
142
137
143
if (empty ($ records )) {
138
144
throw new \UnexpectedValueException ('The single relationship does not refer to any record ' );
@@ -144,7 +150,7 @@ public function getReferredProxyModels(string $proxy, string $name): array
144
150
return $ models ;
145
151
}
146
152
147
- public function isReferenceLoaded (string $ name ): bool
153
+ public function hasReferencedRecords (string $ name ): bool
148
154
{
149
155
return isset ($ this ->references [$ name ]);
150
156
}
@@ -153,33 +159,45 @@ public function isReferenceLoaded(string $name): bool
153
159
* @param string $name
154
160
* @return Record[]
155
161
*/
156
- public function getReference (string $ name ): array
162
+ public function getReferencedRecords (string $ name ): array
157
163
{
158
164
if (!isset ($ this ->references [$ name ])) {
159
- throw new \RuntimeException ("Cannot access relation '$ name' that has not been provided " );
165
+ throw new \RuntimeException ("The referenced records for the relationship '$ name' have not been filled " );
160
166
}
161
167
162
168
return $ this ->references [$ name ];
163
169
}
164
170
165
- public function fillReference (string $ name , array $ records ): void
171
+ /**
172
+ * @param string $name
173
+ * @param Record[] $records
174
+ */
175
+ public function fillReferencedRecords (string $ name , array $ records ): void
166
176
{
167
- $ reference = $ this ->getSchema ()->getReference ($ name );
177
+ $ relationship = $ this ->getSchema ()->getRelationship ($ name );
178
+
179
+ if (\count ($ records ) > 1 && $ relationship ->isUniqueRelationship ()) {
180
+ throw new \InvalidArgumentException ('A unique relationship cannot reference more than a single record ' );
181
+ }
168
182
169
183
foreach ($ records as $ record ) {
170
- if (!$ this ->isRelated ($ reference , $ record )) {
184
+ if (!$ this ->isRelated ($ relationship , $ record )) {
171
185
throw new \InvalidArgumentException ('The provided records are not related to this record ' );
172
186
}
173
187
}
174
188
175
- if (\count ($ records ) > 1 && $ reference ->isSingleRelationship ()) {
176
- throw new \InvalidArgumentException ('The relationship cannot reference more than a single record ' );
189
+ if ($ relationship ->getReverseRelationship ()->isUniqueRelationship ()) {
190
+ $ reverse = $ relationship ->getReverseRelationship ()->getName ();
191
+
192
+ foreach ($ records as $ record ) {
193
+ $ record ->references [$ reverse ] = [$ this ];
194
+ }
177
195
}
178
196
179
197
$ this ->references [$ name ] = array_values ($ records );
180
198
}
181
199
182
- private function isRelated (Reference $ reference , Record $ record ): bool
200
+ private function isRelated (Relationship $ reference , Record $ record ): bool
183
201
{
184
202
if ($ reference ->getReferencedSchema () !== $ record ->getSchema ()) {
185
203
return false ;
0 commit comments