Comprehensive Laravel development guidelines covering conventions, testing, Inertia.js, Eloquent, Pest testing, and Laravel 12 best practices for the Aiku ERP application.
This skill has been flagged as potentially dangerous. It contains patterns that could compromise your security or manipulate AI behavior.Safety score: 35/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
Expert-level Laravel development guidelines specifically curated for building modern Laravel applications with Inertia.js, Pest testing, and Laravel ecosystem best practices.
1. **Write clear, self-explanatory code** - NO code comments unless dealing with very complex logic
2. **Follow existing conventions** - Check sibling files for structure, approach, and naming patterns
3. **Test everything** - Every change must be programmatically tested
4. **Use Laravel's built-in features** - Prefer framework solutions over custom implementations
This skill is optimized for Laravel applications using:
```php
// ✅ CORRECT: Constructor property promotion with explicit types
public function __construct(
public GitHub $github,
public string $apiKey
) {}
// ✅ CORRECT: Explicit return types and parameter hints
protected function isAccessible(User $user, ?string $path = null): bool
{
return $user->hasAccess($path);
}
// ❌ WRONG: Empty constructors
public function __construct() {}
// ❌ WRONG: Missing return types
public function getUsers()
{
return User::all();
}
```
Always use curly braces, even for single-line statements:
```php
// ✅ CORRECT
if ($condition) {
return true;
}
// ❌ WRONG
if ($condition) return true;
```
Always use `php artisan make:` commands to create new files:
```bash
php artisan make:controller --no-interaction
php artisan make:model User --factory --seed --migration
php artisan make:class Services/PaymentProcessor
php artisan make:test --pest UserTest
```
```php
// ✅ CORRECT: Use Eloquent relationships with type hints
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
// ✅ CORRECT: Prevent N+1 queries with eager loading
$users = User::with(['posts', 'comments'])->get();
// ✅ CORRECT: Use query builder for complex operations
$results = User::query()
->whereHas('posts', fn($q) => $q->where('published', true))
->latest()
->limit(10)
->get();
// ❌ WRONG: Avoid DB:: facade when Eloquent works
DB::table('users')->get();
// ❌ WRONG: Avoid raw queries
DB::select('SELECT * FROM users WHERE id = ?', [1]);
```
This project uses **Laravel 10 structure** (pre-Laravel 11 streamlining):
**Important**: NO `bootstrap/app.php` application configuration file.
When modifying columns, **always include all previously defined attributes** or they will be dropped:
```php
Schema::table('users', function (Blueprint $table) {
// ✅ CORRECT: Include all attributes
$table->string('email', 255)->nullable()->unique()->change();
// ❌ WRONG: Missing attributes will be dropped
$table->string('email')->change();
});
```
Always create Form Request classes instead of inline validation:
```php
// ✅ CORRECT: Dedicated Form Request
php artisan make:request StoreUserRequest
class StoreUserRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'unique:users'],
];
}
public function messages(): array
{
return [
'name.required' => 'The name field is required.',
'email.unique' => 'This email is already registered.',
];
}
}
// Controller usage
public function store(StoreUserRequest $request)
{
$user = User::create($request->validated());
}
```
```php
// ✅ CORRECT: Use config() outside of config files
config('app.name')
// ❌ WRONG: Never use env() outside config files
env('APP_NAME')
```
```php
// ✅ CORRECT: Named routes
return redirect()->route('users.show', $user);
// ❌ WRONG: Hardcoded URLs
return redirect('/users/' . $user->id);
```
```php
// routes/web.php
Route::get('/users', function () {
return Inertia::render('Users/Index', [
'users' => User::all()
]);
});
```
```vue
<script setup>
const props = defineProps({
users: Array // Deferred prop
})
</script>
<template>
<!-- Show skeleton while loading -->
<div v-if="!users" class="animate-pulse">
<div class="h-8 bg-gray-200 rounded mb-4"></div>
<div class="h-8 bg-gray-200 rounded mb-4"></div>
</div>
<!-- Show content when loaded -->
<div v-else>
<UserList :users="users" />
</div>
</template>
```
```vue
<script setup>
import { Form } from '@inertiajs/vue3'
</script>
<template>
<Form
:action="route('users.store')"
method="post"
resetOnSuccess
resetOnError
>
<input v-model="form.name" name="name" />
<input v-model="form.email" name="email" />
<button type="submit">Submit</button>
</Form>
</template>
```
```php
// ✅ CORRECT: Pest syntax
it('creates a user successfully', function () {
$response = $this->postJson('/api/users', [
'name' => 'John Doe',
'email' => '[email protected]'
]);
$response->assertSuccessful();
expect(User::count())->toBe(1);
});
// ✅ CORRECT: Use specific assertion methods
$response->assertForbidden();
$response->assertNotFound();
// ❌ WRONG: Generic status assertions
$response->assertStatus(403);
$response->assertStatus(404);
```
```php
// ✅ CORRECT: Use factories for test data
it('shows user posts', function () {
$user = User::factory()
->has(Post::factory()->count(5))
->create();
$response = $this->get(route('users.posts', $user));
$response->assertSuccessful();
expect($response->json('data'))->toHaveCount(5);
});
```
```bash
php artisan test
php artisan test tests/Feature/UserTest.php
php artisan test --filter=testUserCreation
```
**Always run Laravel Pint before finalizing changes:**
```bash
vendor/bin/pint --dirty
```
```php
// Create resource
php artisan make:resource UserResource
class UserResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts' => PostResource::collection($this->whenLoaded('posts')),
];
}
}
// Controller usage
public function index()
{
return UserResource::collection(
User::with('posts')->paginate(20)
);
}
```
Structure API routes with versioning:
```php
// routes/api.php
Route::prefix('v1')->group(function () {
Route::apiResource('users', UserController::class);
});
```
```php
// Create job
php artisan make:job ProcessUserImport
class ProcessUserImport implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public User $user) {}
public function handle(): void
{
// Time-consuming operation
}
}
// Dispatch
ProcessUserImport::dispatch($user);
```
```php
// ✅ CORRECT: Limit eagerly loaded records (Laravel 11+)
$users = User::with([
'posts' => fn($query) => $query->latest()->limit(10)
])->get();
```
```php
// Use Gates
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
// Use Policies
php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
}
```
1. **Never remove tests** without approval - they are core to the application
2. **Do not create new base folders** without approval - stick to existing structure
3. **Do not change dependencies** without approval
4. **No documentation files** unless explicitly requested
5. **Be concise** - focus on what's important, not obvious details
6. **Check for reusable components** before creating new ones
7. **Use descriptive names** - e.g., `isRegisteredForDiscounts()` not `discount()`
1. **Check existing conventions** in sibling files
2. **Use Artisan commands** to generate files
3. **Write clear, typed code** with no comments
4. **Create/update tests** for all changes
5. **Run targeted tests** to verify changes
6. **Format code** with `vendor/bin/pint --dirty`
7. **Ask user** if full test suite should run
This skill ensures Laravel applications are built following framework best practices, maintain high code quality, and leverage the full power of the Laravel ecosystem.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/laravel-boost-ai-guidelines/raw