Skip to content

Commit 1416e0a

Browse files
committed
ManyToMany relations can be set with assignment
1 parent 0c8dd17 commit 1416e0a

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

Tests/Unit/ManyToManyTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ class ManyToManyTest extends \PHPUnit\Framework\TestCase
66
{
77
public function testManyToMany() : void
88
{
9+
$transaction = new \PHPFUI\ORM\Transaction();
910
$product = new \Tests\Fixtures\Record\Product(43);
1011
$this->assertTrue($product->loaded());
1112
$suppliers = $product->suppliers;
1213
$this->assertCount(2, $suppliers);
1314
$this->assertEquals('Supplier C', $suppliers->current()->company);
15+
$supplier = new \Tests\App\Record\Supplier(10);
16+
$this->assertTrue($supplier->loaded(), 'Supplier J not found');
17+
$product->suppliers = $supplier;
18+
$this->assertCount(3, $product->suppliers);
19+
$this->assertTrue($transaction->rollBack());
1420
}
1521
}

docs/5. Virtual Fields.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,31 @@ class Supplier extends \Tests\Fixtures\Record\Definition\Supplier
119119
}
120120
```
121121

122-
### Usage
122+
Many To Many relationships also support adding records to the relations with a simple assignment. The added record is inserted automatically and should not be previously inserted.
123+
124+
## Morph Many
125+
Morph Many relationships (ala Eloquent) can be easily constructed with a junction table containing the primary keys of the two tables you want with a many to many relationship.
126+
127+
For the Product and Employee tables to share image records, you need to add this:
128+
```php
129+
class Product extends \Tests\Fixtures\Record\Definition\Product
130+
{
131+
protected static array $virtualFields = [
132+
'photos' => [\PHPFUI\ORM\MorphMany::class, \Tests\App\Table\Image::class, 'imagable', ],
133+
];
134+
}
135+
136+
class Employee extends \Tests\Fixtures\Record\Definition\Employee
137+
{
138+
protected static array $virtualFields = [
139+
'photos' => [\PHPFUI\ORM\MorphMany::class, \Tests\App\Table\Image::class, 'imagable', ],
140+
];
141+
}
142+
```
143+
144+
Morph Many relationships also support adding records to the relations with a simple assignment. The added record is inserted automatically and should not be previously inserted.
145+
146+
#### Usage
123147
```php
124148
$product = new \App\Record\Product(4);
125149
$suppliers = $product->suppliers;

src/PHPFUI/ORM/ManyToMany.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
class ManyToMany extends \PHPFUI\ORM\VirtualField
2121
{
2222
/**
23-
* @param array<string, string[]> $parameters Key is the field name, values should be **\PHPFUI\ORM\ManyToMany::class**, followed by the junction table class name, then related table class name. Two additional parameters can be specified, the order by column and sort order (defaults to ASC).
23+
* @param array<string> $parameters values are the junction table class name, then related table class name. Two additional parameters can be specified, the order by column and sort order (defaults to ASC).
2424
*/
2525
public function getValue(array $parameters) : \PHPFUI\ORM\RecordCursor
2626
{
@@ -55,4 +55,26 @@ public function getValue(array $parameters) : \PHPFUI\ORM\RecordCursor
5555

5656
return $relatedTable->getRecordCursor();
5757
}
58+
59+
/**
60+
* @param mixed $value to set
61+
* @param array<string> $parameters values are the junction table class name, then related table class name. Two additional parameters can be specified, the order by column and sort order (defaults to ASC).
62+
*/
63+
public function setValue(mixed $value, array $parameters) : void
64+
{
65+
$junctionTableClass = \array_shift($parameters);
66+
$junctionTable = new $junctionTableClass();
67+
$junctionRecord = clone $junctionTable->getRecord();
68+
69+
foreach ($this->currentRecord->getPrimaryKeys() as $key)
70+
{
71+
$junctionRecord->{$key} = $this->currentRecord->{$key};
72+
}
73+
74+
foreach ($value->getPrimaryKeys() as $key)
75+
{
76+
$junctionRecord->{$key} = $value->{$key};
77+
}
78+
$junctionRecord->insert();
79+
}
5880
}

0 commit comments

Comments
 (0)