Eloquent relationships keep evolving. Laravel 5.8 adds has-one-through, simplifying complex relationships. Email verification routes become automatic, reducing boilerplate. At ZIRA Software, these features streamline application architecture.
Has-One-Through Relationship
Access distant relationships:
// Example: Supplier -> User -> Phone
// Get supplier's phone through user
// app/Models/Supplier.php
class Supplier extends Model
{
public function user()
{
return $this->hasOne(User::class);
}
// New in 5.8: Has-one-through
public function phone()
{
return $this->hasOneThrough(
Phone::class, // Final model
User::class // Intermediate model
);
}
}
// Usage
$supplier = Supplier::find(1);
$phone = $supplier->phone; // Direct access!
Real-world example:
// Country -> Mechanic -> Car
// Get country's car through mechanic
class Country extends Model
{
public function mechanics()
{
return $this->hasMany(Mechanic::class);
}
public function cars()
{
return $this->hasManyThrough(Car::class, Mechanic::class);
}
// Get first car
public function car()
{
return $this->hasOneThrough(Car::class, Mechanic::class);
}
}
Email Verification Routes
Automatic route registration:
// Before 5.8: Manual route definition
Route::get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
Route::get('email/verify/{id}', 'Auth\VerificationController@verify')->name('verification.verify');
Route::get('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
// After 5.8: Automatic
Auth::routes(['verify' => true]);
Usage:
// app/User.php
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
}
// routes/web.php
Route::get('/dashboard', function () {
// Only verified users
})->middleware(['auth', 'verified']);
Policy Auto-Discovery
Automatic policy resolution:
// Before: Manual registration in AuthServiceProvider
protected $policies = [
Post::class => PostPolicy::class,
Comment::class => CommentPolicy::class,
];
// After 5.8: Automatic discovery
// If app/Policies/PostPolicy.php exists, it's automatically discovered
Convention:
- Model:
App\Post - Policy:
App\Policies\PostPolicy
Token Guard Token Hashing
Improved security:
// API tokens now hashed in database
// Before: plain text storage
// After: hashed like passwords
// When creating tokens
$token = $user->createToken('app-token')->plainTextToken;
// Store plain token ONLY in response
return response()->json(['token' => $token]);
Scheduler Timezone
Per-task timezone:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// Before: All tasks use app timezone
$schedule->command('emails:send')
->daily();
// After 5.8: Per-task timezone
$schedule->command('emails:send')
->daily()
->timezone('America/New_York');
$schedule->command('reports:generate')
->daily()
->timezone('Europe/London');
}
Higher Order orWhere
Cleaner query constraints:
// Before
User::where('status', 'active')
->where(function ($query) {
$query->where('role', 'admin')
->orWhere('role', 'moderator');
})
->get();
// After 5.8: Higher order orWhere
User::where('status', 'active')
->where(function ($query) {
$query->where('role', 'admin')
->orWhere->where('role', 'moderator');
})
->get();
Artisan Call Improvements
Better output handling:
// Call artisan command and capture output
$exitCode = Artisan::call('migrate', [
'--force' => true,
]);
$output = Artisan::output();
// New in 5.8: Pass output to callback
Artisan::call('migrate', ['--force' => true], function ($output) {
// Process output in real-time
logger()->info($output);
});
Mock Testing Improvements
Better mock assertions:
public function test_user_can_upload_avatar()
{
Storage::fake('avatars');
$response = $this->post('/avatar', [
'avatar' => UploadedFile::fake()->image('avatar.jpg')
]);
// New assertion methods
Storage::disk('avatars')->assertExists('avatar.jpg');
Storage::disk('avatars')->assertMissing('old-avatar.jpg');
}
Blade Component Tag
Custom component tags:
{{-- Before --}}
@component('alert')
This is an alert
@endcomponent
{{-- After 5.8: Component tags --}}
<x-alert>
This is an alert
</x-alert>
{{-- With attributes --}}
<x-alert type="error" dismissible>
Error message
</x-alert>
// app/View/Components/Alert.php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
public $type;
public $dismissible;
public function __construct($type = 'info', $dismissible = false)
{
$this->type = $type;
$this->dismissible = $dismissible;
}
public function render()
{
return view('components.alert');
}
}
DynamoDB Cache Driver
AWS DynamoDB support:
// .env
CACHE_DRIVER=dynamodb
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
DYNAMODB_CACHE_TABLE=cache
Carbon 2.0
Updated date library:
use Illuminate\Support\Carbon;
// New methods in Carbon 2.0
$date = Carbon::parse('2018-11-15');
$date->isBirthday();
$date->isSameMonth(now());
$date->isSameQuarter(now());
Conclusion
Laravel 5.8 polishes Eloquent relationships and authentication flows. Has-one-through simplifies complex relationships, while automatic email verification routes reduce boilerplate.
Upgrading or building with Laravel? Contact ZIRA Software for Laravel development services.