Skip to content

Commit 479e882

Browse files
committed
Tweaks the model ID generation.
- New model instances will be prefixed with "create_" instead of suffixed with "_new" - Strip out only the model root namespace when generating the DOM ID
1 parent cc34a20 commit 479e882

File tree

7 files changed

+75
-15
lines changed

7 files changed

+75
-15
lines changed

config/turbo-laravel.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,19 @@
1313
*/
1414

1515
'queue' => true,
16+
17+
/*
18+
|--------------------------------------------------------------------------
19+
| Root Model Namespaces
20+
|--------------------------------------------------------------------------
21+
|
22+
| When generating the DOM ID for models, we need to strip out parts of the namespace, so we
23+
| can more accurate DOM IDs. If you happen to use a different convention for where you place
24+
| your models, please, add the model namespace prefixes here. We'll strip out the first one that
25+
| matches a "Str:startsWith()" check, so sort them from more specific to less specific.
26+
*/
27+
'models_namespace' => [
28+
'App\\Models\\',
29+
'App\\',
30+
],
1631
];

src/Models/Broadcasts.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function hotwireBroadcastUsing()
7777

7878
public function hotwireTargetDomId()
7979
{
80-
return $this->hotwireResolveNamesUsing()->resourceId(static::class, $this->getKey());
80+
return $this->hotwireResolveNamesUsing()->resourceIdFor($this);
8181
}
8282

8383
public function hotwireTargetResourcesName()

src/NamesResolver.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static function resourceName(Model $model, bool $plural = true): string
1414

1515
private static function resourceNameFor(string $modelName, bool $plural = true): string
1616
{
17-
return (string)strtolower(implode('_', preg_split('/(?=[A-Z])/', Str::of($modelName)->camel()->plural($plural ? 2 : 1))));
17+
return (string)strtolower(implode('_', preg_split('/(?=[A-Z])/', Str::of($modelName)->replace('\\', ' ')->camel()->plural($plural ? 2 : 1))));
1818
}
1919

2020
private static function resourceNameSingularFor(string $modelName): string
@@ -63,21 +63,32 @@ public function modelPathToChannelName(string $model, $id)
6363
return "{$path}.{$id}";
6464
}
6565

66-
public static function resourceId($modelClass, $modelId, $prefix = ""): string
66+
public static function resourceIdFor(Model $model, string $prefix = ""): string
6767
{
6868
$prefix = $prefix !== ""
6969
? "{$prefix}_"
7070
: "";
7171

72-
$resource = static::resourceNameSingularFor(class_basename($modelClass));
72+
$resource = static::resourceNameSingularFor(static::getModelWithoutRootNamespaces($model));
73+
74+
if (!($modelId = $model->getKey())) {
75+
return "{$prefix}create_{$resource}";
76+
}
7377

74-
return "{$prefix}{$resource}_{$modelId}";
78+
return trim("{$prefix}{$resource}_{$modelId}", '_');
7579
}
7680

77-
public static function resourceIdFor(Model $model, string $prefix = ""): string
81+
private static function getModelWithoutRootNamespaces(Model $model): string
7882
{
79-
$id = $model->getKey() ?: "new";
83+
$className = get_class($model);
84+
85+
foreach (config('turbo-laravel.models_namespace') as $rootNs) {
86+
if (Str::startsWith($className, $rootNs)) {
87+
return Str::replaceFirst($rootNs, '', $className);
88+
}
89+
}
8090

81-
return static::resourceId(class_basename($model), $id, $prefix);
91+
// If none of the previous matchers work, we use the class_basename helper instead.
92+
return class_basename($model);
8293
}
8394
}

src/TurboStreamModelRenderer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function renderDeleted(Model $model, string $action): ViewContract
3939
return View::make('turbo-laravel::model-removed', [
4040
'target' => method_exists($model, 'hotwireTargetDomId')
4141
? $model->hotwireTargetDomId()
42-
: NamesResolver::resourceId($model, $model->getKey()),
42+
: NamesResolver::resourceIdFor($model),
4343
'action' => $action,
4444
]);
4545
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Tonysm\TurboLaravel\Tests\Views\Models\Account;
4+
5+
class TestModel extends \Tonysm\TurboLaravel\Tests\TestModel
6+
{
7+
}

tests/Views/Models/TestModel.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Tonysm\TurboLaravel\Tests\Views\Models;
4+
5+
class TestModel extends \Tonysm\TurboLaravel\Tests\TestModel
6+
{
7+
}

tests/Views/ViewHelpersTest.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<?php
22

3-
namespace Tonysm\TurboLaravel\Tests\Views\Components;
3+
namespace Tonysm\TurboLaravel\Tests\Views;
44

55
use Illuminate\Support\Facades\View;
66
use Illuminate\Support\Str;
7+
use Tonysm\TurboLaravel\Tests\Views\Models;
78
use function Tonysm\TurboLaravel\dom_id;
89
use Tonysm\TurboLaravel\Tests\TestCase;
9-
use Tonysm\TurboLaravel\Tests\TestModel;
1010
use Tonysm\TurboLaravel\TurboFacade;
1111

1212
class ViewHelpersTest extends TestCase
@@ -27,23 +27,43 @@ public function renders_turbo_native_correctly()
2727
/** @test */
2828
public function renders_dom_id()
2929
{
30-
$testModel = TestModel::create(['name' => 'lorem']);
30+
$testModel = Models\TestModel::create(['name' => 'lorem']);
3131

3232
$renderedDomId = View::file(__DIR__ . '/fixtures/domid.blade.php', ['model' => $testModel])->render();
3333
$renderedDomIdWithPrefix = View::file(__DIR__ . '/fixtures/domid_with_prefix.blade.php', ['model' => $testModel])->render();
34-
$rendersDomIdOfNewModel = View::file(__DIR__ . '/fixtures/domid.blade.php', ['model' => new TestModel()])->render();
34+
$rendersDomIdOfNewModel = View::file(__DIR__ . '/fixtures/domid.blade.php', ['model' => new Models\TestModel()])->render();
3535

3636
$this->assertEquals('<div id="test_model_1"></div>', trim($renderedDomId));
3737
$this->assertEquals('<div id="favorites_test_model_1"></div>', trim($renderedDomIdWithPrefix));
38-
$this->assertEquals('<div id="test_model_new"></div>', trim($rendersDomIdOfNewModel));
38+
$this->assertEquals('<div id="create_test_model"></div>', trim($rendersDomIdOfNewModel));
3939
}
4040

4141
/** @test */
4242
public function can_use_helper_function()
4343
{
44-
$testModel = TestModel::create(['name' => 'lorem']);
44+
$testModel = Models\TestModel::create(['name' => 'lorem']);
4545

4646
$this->assertEquals("test_model_1", dom_id($testModel));
4747
$this->assertEquals("my_context_test_model_1", dom_id($testModel, "my_context"));
4848
}
49+
50+
/** @test */
51+
public function generates_model_ids_for_models_in_nested_folders()
52+
{
53+
config()->set('turbo-laravel.models_namespace', [
54+
__NAMESPACE__.'\\Models\\',
55+
]);
56+
57+
$testModel = Models\TestModel::create(['name' => 'lorem']);
58+
59+
$this->assertEquals("test_model_1", dom_id($testModel));
60+
$this->assertEquals("my_context_test_model_1", dom_id($testModel, "my_context"));
61+
62+
$accountTestModel = Models\Account\TestModel::create(['name' => 'lorem']);
63+
64+
$this->assertEquals("account_test_model_{$accountTestModel->getKey()}", dom_id($accountTestModel));
65+
$this->assertEquals("my_context_account_test_model_{$accountTestModel->getKey()}", dom_id($accountTestModel, "my_context"));
66+
67+
$this->assertEquals("create_account_test_model", dom_id(new Models\Account\TestModel()));
68+
}
4969
}

0 commit comments

Comments
 (0)