Created
May 9, 2025 16:55
-
-
Save bmadigan/6e09d857cea238090c0e181887838491 to your computer and use it in GitHub Desktop.
Laravel ModelsThat - Aaron Francis Inspired
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Traits; | |
use Illuminate\Database\Eloquent\Builder; | |
trait HasEmbedding | |
{ | |
public function scopeNeedsEmbedding(Builder $query): Builder | |
{ | |
return $query->whereNull('embedded_at'); // or a relevant field check | |
} | |
public function scopeReserveFor(Builder $query, string $key, string $duration): Builder | |
{ | |
// Assuming a 'reserved_until' datetime column | |
return $query->where(function ($q) { | |
$q->whereNull('reserved_until') | |
->orWhere('reserved_until', '<', now()); | |
})->tap(function ($query) use ($duration) { | |
$query->update(['reserved_until' => now()->add(strtotime($duration) - time())]); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use App\Models\TestHasEmbeddingModel; | |
use Illuminate\Support\Carbon; | |
test('it filters models needing embedding', function () { | |
TestHasEmbeddingModel::factory()->create(['embedded_at' => null]); | |
TestHasEmbeddingModel::factory()->create(['embedded_at' => now()]); | |
$results = TestHasEmbeddingModel::needsEmbedding()->get(); | |
expect($results)->toHaveCount(1); | |
}); | |
test('it reserves models for a given time', function () { | |
$model = TestHasEmbeddingModel::factory()->create(['reserved_until' => null]); | |
TestHasEmbeddingModel::reserveFor('embeddings:create', '+2 hours')->get(); | |
$model->refresh(); | |
expect($model->reserved_until)->toBeInstanceOf(Carbon::class); | |
expect($model->reserved_until->gt(now()))->toBeTrue(); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Helpers; | |
use Illuminate\Support\Str; | |
use Illuminate\Support\Facades\File; | |
use ReflectionClass; | |
class ModelsThat | |
{ | |
public static function useTrait(string $trait): \Illuminate\Support\Collection | |
{ | |
$modelsPath = app_path('Models'); | |
$modelsNamespace = 'App\\Models\\'; | |
return collect(File::allFiles($modelsPath)) | |
->filter(fn ($file) => Str::endsWith($file->getFilename(), '.php')) | |
->map(function ($file) use ($modelsNamespace) { | |
$class = $modelsNamespace . $file->getBasename('.php'); | |
if (! class_exists($class)) { | |
require_once $file->getPathname(); | |
} | |
return $class; | |
}) | |
->filter(function ($class) use ($trait) { | |
return in_array($trait, class_uses_recursive($class)); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use App\Helpers\ModelsThat; | |
use App\Models\TestHasEmbeddingModel; | |
use App\Traits\HasEmbedding; | |
use Illuminate\Support\Collection; | |
beforeEach(function () { | |
// Simulate autoloading | |
require_once app_path('Models/TestHasEmbeddingModel.php'); | |
}); | |
test('it returns models using the HasEmbedding trait', function () { | |
$models = ModelsThat::useTrait(HasEmbedding::class); | |
expect($models)->toBeInstanceOf(Collection::class); | |
expect($models)->toContain(TestHasEmbeddingModel::class); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment