Skip to content

Commit 235c5a1

Browse files
authored
BelongsTo field (#7)
* Handle belongsTo field * Doc * Typo
1 parent 3bb62f3 commit 235c5a1

File tree

4 files changed

+118
-9
lines changed

4 files changed

+118
-9
lines changed

README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,63 @@ class Project extends Model
106106
> [!NOTE]
107107
> This configuration will be used by Ozu to properly display the collection in the content management tool. It has no effect in your local codebase.
108108
109-
### Attachments and visuals are `Media`s
109+
### Handle `BelongsTo` relationships
110+
111+
A common use case is to have a `BelongsTo` relationship between two Ozu Models. There are two possibilities:
112+
- the relationship is not exposed to Ozu, meaning you don't want to handle it in the CMS: in this case you can define the relationship as usual in Laravel, with a dedicated DB column for the foreign key.
113+
- If you more likely need to allow the content manager to update this relation, then there is a major contraint: you can only have one belongsTo relation per Model, with a column named `parent_id`.
114+
115+
Here is an example with a `Project` Model that belongs to a `Category` Model. First the migration:
116+
117+
```php
118+
return new class extends Migration
119+
{
120+
use MigratesOzuTable;
121+
122+
public function up(): void
123+
{
124+
$this->createOzuTable('projects');
125+
126+
Schema::table('projects', function (Blueprint $table) {
127+
$table->foreignId('parent_id')->constrained('categories')->cascadeOnDelete();
128+
// ...
129+
});
130+
}
131+
};
132+
```
133+
134+
Then the `Project` Model:
135+
136+
```php
137+
class Project extends Model
138+
{
139+
use IsOzuModel;
140+
141+
public function category(): BelongsTo
142+
{
143+
return $this->belongsTo(Category::class, 'parent_id');
144+
}
145+
146+
// ...
147+
148+
public static function configureOzuCollectionForm(OzuCollectionFormConfig $config): OzuCollectionFormConfig
149+
{
150+
return $config
151+
->declareBelongsToField(ozuModelClass: Category::class, label: 'Project Category')
152+
->addCustomField(/* ... */);
153+
// ...
154+
}
155+
156+
// ...
157+
}
158+
```
159+
160+
With that, you can use the regular `$project->category` relationship in your codebase, and Ozu will be able to present a category selector in the Project form on the CMS.
161+
162+
> [!NOTE]
163+
> You can of course define the `HasMany` opposite of this relation in the Category Model if needed.
164+
165+
### Attached visuals are `Media`
110166

111167
If you want to attach images to your Models, leverage the `Code16\OzuClient\Eloquent\Media` model via a `MorphOne` or a `MorphMany` relation:
112168

src/OzuCms/Form/OzuBelongsToField.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Code16\OzuClient\OzuCms\Form;
4+
5+
class OzuBelongsToField extends OzuField
6+
{
7+
protected bool $clearable = false;
8+
9+
public function __construct(
10+
protected string $ozuCollectionKey
11+
) {
12+
parent::__construct('parent_id');
13+
}
14+
15+
public function type(): string
16+
{
17+
return 'belongsTo';
18+
}
19+
20+
public function setClearable(bool $clearable = true): self
21+
{
22+
$this->clearable = $clearable;
23+
24+
return $this;
25+
}
26+
27+
public function toArray(): array
28+
{
29+
return array_merge(parent::toArray(), [
30+
'collectionKey' => $this->ozuCollectionKey,
31+
'clearable' => $this->clearable,
32+
]);
33+
}
34+
}
35+

src/OzuCms/OzuCollectionFormConfig.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
namespace Code16\OzuClient\OzuCms;
44

5+
use Code16\OzuClient\OzuCms\Form\OzuBelongsToField;
56
use Code16\OzuClient\OzuCms\Form\OzuField;
67
use Illuminate\Support\Collection;
78

89
class OzuCollectionFormConfig
910
{
1011
protected array $fields = [];
12+
protected ?OzuBelongsToField $belongsToField = null;
1113

1214
public function addCustomField(OzuField $field): self
1315
{
@@ -16,8 +18,23 @@ public function addCustomField(OzuField $field): self
1618
return $this;
1719
}
1820

21+
public function declareBelongsToField(string $ozuModelClass, string $label, bool $required = true): self
22+
{
23+
$ozuCollectionKey = app($ozuModelClass)->ozuCollectionKey();
24+
25+
$this->belongsToField = (new OzuBelongsToField($ozuCollectionKey))
26+
->setLabel($label)
27+
->setClearable(!$required)
28+
->setValidationRules($required ? ['required'] : []);
29+
30+
return $this;
31+
}
32+
1933
public function customFields(): Collection
2034
{
21-
return collect($this->fields);
35+
return collect([
36+
$this->belongsToField,
37+
...$this->fields
38+
])->whereNotNull();
2239
}
2340
}

src/Support/Database/MigratesOzuTable.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
namespace Code16\OzuClient\Support\Database;
44

5+
use Illuminate\Database\Schema\Blueprint;
56
use Illuminate\Support\Facades\Schema;
67

78
trait MigratesOzuTable
89
{
910
protected function createOzuTable(string $table): void
1011
{
11-
Schema::create($table, function ($table) {
12-
$table->id();
13-
$table->text('title')->nullable();
14-
$table->text('content')->nullable();
15-
$table->string('slug')->nullable();
16-
$table->unsignedInteger('order')->default(1000);
17-
$table->timestamps();
12+
Schema::create($table, function (Blueprint $blueprint) {
13+
$blueprint->id();
14+
$blueprint->text('title')->nullable();
15+
$blueprint->text('content')->nullable();
16+
$blueprint->string('slug')->nullable();
17+
$blueprint->unsignedInteger('order')->default(1000);
18+
$blueprint->timestamps();
1819
});
1920
}
2021
}

0 commit comments

Comments
 (0)