03: Laravel's Developer Experience: Productivity & Tools

03: Laravel’s Developer Experience Intermediate
Section titled “03: Laravel’s Developer Experience Intermediate”Overview
Section titled “Overview”Laravel’s developer experience tools are where Laravel truly shines. If you’ve worked with Rails’ command-line tools like rails generate, rails console, or Rake tasks, you’ll find Laravel’s Artisan CLI familiar yet more powerful in some areas. Laravel follows Rails’ “convention over configuration” philosophy, meaning you spend less time configuring and more time building.
This chapter explores Laravel’s productivity tools from a Rails developer’s perspective, showing you how to be productive immediately.
Prerequisites
Section titled “Prerequisites”Before starting this chapter, you should have:
- Completion of Chapter 02: Modern PHP: What’s Changed or equivalent understanding of modern PHP features
- PHP 8.4+ installed and confirmed working with
php --version - Composer installed globally (for Laravel project creation)
- Basic familiarity with command-line tools
- Estimated Time: ~60-90 minutes
Verify your setup:
# Check PHP versionphp --version
# Check Composer installationcomposer --version
# Verify Laravel installer (optional but recommended)composer global require laravel/installerlaravel --versionNote: This chapter is reference-heavy and focuses on command-line tools. You don’t need a Laravel project running to follow along, but having one will help you practice the commands.
What You’ll Build
Section titled “What You’ll Build”By the end of this chapter, you will have:
- A comprehensive command reference comparing Rails and Laravel tools
- Understanding of Artisan CLI and how it compares to Rails commands
- Knowledge of code generation patterns in Laravel
- Familiarity with Tinker (Laravel’s interactive console)
- Understanding of Laravel’s built-in queue and scheduling systems
- Setup instructions for debugging tools (Telescope, Debugbar, Ray)
- Custom Artisan command examples
- IDE configuration recommendations for Laravel development
📦 Code Samples
Section titled “📦 Code Samples”Complete Artisan command examples are available on GitHub:
- Custom Artisan Commands — SendDigest command, CreateUser interactive command, SetupEnvironment with choices
View all code samples:
git clone https://github.com/dalehurley/codewithphp.gitcd codewithphp/code/rails-developers-love-laravel/chapter-03Objectives
Section titled “Objectives”- Understand Artisan CLI and how it compares to Rails commands
- Master code generation patterns for models, controllers, and migrations
- Use Tinker (Laravel’s REPL) effectively for interactive development
- Configure development servers and local environments (Valet, Sail)
- Manage databases with migration and seeding commands
- Implement queue workers and background job processing
- Set up task scheduling without manual cron configuration
- Create custom Artisan commands with rich interactions
- Configure IDE support and debugging tools (Telescope, Debugbar, Ray)
Quick Command Reference
Section titled “Quick Command Reference”| Task | Rails | Laravel |
|---|---|---|
| Create project | rails new app | laravel new app |
| Dev server | rails server | artisan serve |
| Console/REPL | rails console | artisan tinker |
| Generate model | rails g model User | artisan make:model User |
| Generate controller | rails g controller Users | artisan make:controller UserController |
| Generate migration | rails g migration AddX | artisan make:migration add_x |
| Run migrations | rails db:migrate | artisan migrate |
| Rollback | rails db:rollback | artisan migrate:rollback |
| Seed database | rails db:seed | artisan db:seed |
| List routes | rails routes | artisan route:list |
| Run tests | rails test or rspec | artisan test |
| Clear cache | rails tmp:clear | artisan cache:clear |
| Storage link | N/A | artisan storage:link |
| Generate view | N/A | artisan make:view posts.index |
| Generate component | N/A | artisan make:component Alert |
| Queue table | N/A | artisan queue:table |
1. Artisan CLI
Section titled “1. Artisan CLI”Laravel’s Artisan is equivalent to Rails’ command-line tool. Every command starts with php artisan.
Getting Help
Section titled “Getting Help”Rails:
rails --helprails generate --helprails db:migrate --helpLaravel:
php artisanphp artisan listphp artisan help migratephp artisan migrate --helpCommon Artisan Commands
Section titled “Common Artisan Commands”# See all available commandsphp artisan list
# Get help on a commandphp artisan help make:controller
# Run with verbose outputphp artisan migrate -v
# Run in specific environmentphp artisan migrate --env=production2. Code Generation
Section titled “2. Code Generation”Models
Section titled “Models”Rails:
# Generate modelrails generate model User name:string email:string
# Generate model with migrationrails g model Post title:string body:text user:referencesLaravel:
# Generate model onlyphp artisan make:model User
# Generate model with migrationphp artisan make:model User -m
# Generate model with migration, factory, and seederphp artisan make:model User -mfs
# Generate model with everything (migration, factory, seeder, controller, resource)php artisan make:model User --all
# Shortcutsphp artisan make:model User -mcr # Model, migration, controller (resource)Controllers
Section titled “Controllers”Rails:
# Basic controllerrails g controller Users
# Controller with actionsrails g controller Users index show create update destroy
# API controllerrails g controller api/UsersLaravel:
# Basic controllerphp artisan make:controller UserController
# Resource controller (with CRUD methods)php artisan make:controller UserController --resource
# API resource controller (without create/edit views)php artisan make:controller UserController --api
# Invokable controller (single action)php artisan make:controller ShowProfile --invokable
# Controller in subdirectoryphp artisan make:controller Api/UserControllerMigrations
Section titled “Migrations”Rails:
# Create migrationrails g migration CreateUsers name:string email:stringrails g migration AddRoleToUsers role:stringLaravel:
# Create migrationphp artisan make:migration create_users_tablephp artisan make:migration add_role_to_users_table
# Laravel infers table name from migration name# create_users_table → creates users table# add_role_to_users_table → modifies users tableOther Generators
Section titled “Other Generators”Rails:
rails g scaffold Post title:string body:textrails g mailer UserMailerrails g job ProcessPodcastLaravel:
# No built-in scaffold, but can generate componentsphp artisan make:controller PostController --resourcephp artisan make:model Post -m
# Mailphp artisan make:mail WelcomeEmail
# Jobphp artisan make:job ProcessPodcast
# Eventphp artisan make:event UserRegistered
# Listenerphp artisan make:listener SendWelcomeEmail --event=UserRegistered
# Request (form validation)php artisan make:request StoreUserRequest
# Middlewarephp artisan make:middleware CheckAge
# Seederphp artisan make:seeder UserSeeder
# Factoryphp artisan make:factory UserFactory
# Policy (authorization)php artisan make:policy PostPolicy --model=Post
# Resource (API transformation)php artisan make:resource UserResource
# Testphp artisan make:test UserTestphp artisan make:test UserTest --unit
# View (Blade template)php artisan make:view posts.index
# Component (Blade component)php artisan make:component Alertphp artisan make:component Alert --inline # Inline component
# Notificationphp artisan make:notification InvoicePaid
# Observer (model lifecycle hooks)php artisan make:observer PostObserver --model=Post
# Service Providerphp artisan make:provider CustomServiceProvider
# Channel (broadcasting)php artisan make:channel OrderChannel
# Exceptionphp artisan make:exception CustomException3. Tinker (Interactive Console)
Section titled “3. Tinker (Interactive Console)”Laravel’s Tinker is equivalent to rails console.
Rails Console:
rails console
# In consoleuser = User.firstuser.name = "Jane"user.save
User.where(active: true).countPost.create(title: "Hello", body: "World")Laravel Tinker:
php artisan tinker
# In Tinker>>> $user = User::first();>>> $user->name = "Jane";>>> $user->save();
>>> User::where('active', true)->count();>>> Post::create(['title' => 'Hello', 'body' => 'World']);
# Tinker-specific helpers>>> $this // Show available bindings>>> help() // Show help>>> clear // Clear screen::: tip Tinker Shortcuts Tinker includes helpful shortcuts:
$thisshows available variables- Tab completion for methods
- History navigation with arrow keys
- Multi-line input support :::
4. Development Server
Section titled “4. Development Server”Rails:
# Start server (default port 3000)rails server
# Custom portrails server -p 4000
# Bind to all interfacesrails server -b 0.0.0.0Laravel:
# Start server (default port 8000)php artisan serve
# Custom portphp artisan serve --port=8080
# Custom hostphp artisan serve --host=0.0.0.0
# Run in background (Unix)php artisan serve > /dev/null 2>&1 &::: tip Hot Reloading with Laravel Mix/Vite Laravel’s asset compilation tools (Mix or Vite) support hot module replacement (HMR) for instant browser updates:
# With Vite (Laravel 9+)npm run dev # Starts Vite dev server with HMR
# With Laravel Mix (older projects)npm run watch # Watches for changes and recompilesUnlike Rails’ asset pipeline, Laravel’s frontend tools provide true hot reloading—changes to CSS/JS update in the browser without a full page refresh. :::
Laravel Valet (macOS) vs Pow
Section titled “Laravel Valet (macOS) vs Pow”If you use Pow or Puma-dev on Rails, Laravel Valet is the equivalent:
# Install Valet (macOS)composer global require laravel/valetvalet install
# Park directory (serves all subdirectories)cd ~/Sitesvalet park
# Now myapp.test works automatically!
# Or link individual projectcd ~/Projects/myappvalet link
# Secure with HTTPSvalet secure myapp5. Database Management
Section titled “5. Database Management”Running Migrations
Section titled “Running Migrations”Rails:
rails db:migraterails db:rollbackrails db:rollback STEP=3rails db:migrate:statusrails db:resetLaravel:
php artisan migratephp artisan migrate:rollbackphp artisan migrate:rollback --step=3php artisan migrate:status
# Fresh (drop all tables and re-migrate)php artisan migrate:fresh
# Fresh with seedphp artisan migrate:fresh --seed
# Reset (rollback all, then re-migrate)php artisan migrate:reset
# Refresh (rollback and re-migrate)php artisan migrate:refreshDatabase Seeding
Section titled “Database Seeding”Rails:
rails db:seedrails db:seed:replant # Clear and re-seedLaravel:
php artisan db:seed
# Run specific seederphp artisan db:seed --class=UserSeeder
# Fresh migrate with seedphp artisan migrate:fresh --seedDatabase Inspection
Section titled “Database Inspection”Laravel:
# Show database tablesphp artisan db:show
# Show table schemaphp artisan db:table users
# Monitor database queriesphp artisan db:monitor --max=100Storage Management
Section titled “Storage Management”Laravel:
# Create symbolic link for public storagephp artisan storage:link
# This links storage/app/public to public/storage# Allows serving uploaded files via public URL6. Queue Workers
Section titled “6. Queue Workers”Both frameworks support background jobs. Rails uses Sidekiq, Resque, or ActiveJob. Laravel has built-in queue support.
Rails (ActiveJob + Sidekiq):
# Start Sidekiqbundle exec sidekiq
# Queue a jobUserMailer.welcome_email(@user).deliver_laterLaravel:
# Create queue table (first time setup)php artisan queue:tablephp artisan migrate
# Create notifications table (for database notifications)php artisan notifications:tablephp artisan migrate
# Start queue workerphp artisan queue:work
# Process specific queuephp artisan queue:work --queue=emails,default
# Process one jobphp artisan queue:work --once
# Listen (restarts automatically)php artisan queue:listen
# Restart all workersphp artisan queue:restart
# View failed jobsphp artisan queue:failed
# Retry failed jobphp artisan queue:retry 1
# Retry all failed jobsphp artisan queue:retry all
# Flush failed jobsphp artisan queue:flush
# Queue a jobMail::to($user)->queue(new WelcomeEmail());::: tip Horizon for Queue Management
Laravel Horizon provides a beautiful dashboard for monitoring queues (like Sidekiq Web UI). Install with composer require laravel/horizon.
:::
7. Task Scheduling
Section titled “7. Task Scheduling”Rails (whenever gem or cron):
every 1.day, at: '4:30 am' do rake 'emails:send_digest'endLaravel (built-in scheduler):
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel{ protected function schedule(Schedule $schedule) { $schedule->command('emails:send-digest') ->daily() ->at('04:30');
$schedule->call(function () { // Inline task })->everyMinute();
// More examples $schedule->command('backup:run')->weekly(); $schedule->job(new ProcessPodcast)->hourly(); $schedule->exec('node script.js')->dailyAt('13:00'); }}Then add one cron entry:
* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1Laravel handles all scheduling internally!
8. Cache Management
Section titled “8. Cache Management”Rails:
rails tmp:cache:clearRails.cache.clear # In consoleLaravel:
# Clear application cachephp artisan cache:clear
# Clear route cachephp artisan route:clear
# Clear config cachephp artisan config:clear
# Clear view cachephp artisan view:clear
# Clear compiled class filesphp artisan clear-compiled
# Clear everythingphp artisan optimize:clear9. Route Management
Section titled “9. Route Management”Rails:
# List all routesrails routes
# Search routesrails routes | grep users
# Routes for specific controllerrails routes -c UsersLaravel:
# List all routesphp artisan route:list
# Filter by namephp artisan route:list --name=user
# Filter by pathphp artisan route:list --path=api
# Filter by methodphp artisan route:list --method=GET
# Show middlewarephp artisan route:list --except-vendor
# Compact outputphp artisan route:list --compact
# Cache routes (production)php artisan route:cache
# Clear route cachephp artisan route:clear10. Custom Artisan Commands
Section titled “10. Custom Artisan Commands”Creating Commands
Section titled “Creating Commands”Rails (Rake task):
namespace :users do desc "Send weekly digest emails" task send_digest: :environment do User.active.find_each do |user| UserMailer.weekly_digest(user).deliver_now end endend
# Run: rails users:send_digestLaravel:
# Generate commandphp artisan make:command SendDigest<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SendDigest extends Command{ protected $signature = 'users:send-digest {--queue : Queue the emails}';
protected $description = 'Send weekly digest emails';
public function handle() { $this->info('Sending digest emails...');
$bar = $this->output->createProgressBar(100);
User::active()->chunk(100, function ($users) use ($bar) { foreach ($users as $user) { Mail::to($user)->send(new WeeklyDigest($user)); $bar->advance(); } });
$bar->finish(); $this->newLine(); $this->info('Emails sent successfully!'); }}
// Run: php artisan users:send-digest// Run: php artisan users:send-digest --queueCommand Features
Section titled “Command Features”Laravel commands support rich interactions:
<?php
// Ask for input$name = $this->ask('What is your name?');
// Ask with default$name = $this->ask('What is your name?', 'John');
// Secret input (password)$password = $this->secret('Password?');
// Confirmationif ($this->confirm('Do you wish to continue?')) { // Continue}
// Choice$role = $this->choice('Select role', ['admin', 'user'], 'user');
// Output styling$this->info('Information message');$this->error('Error message');$this->warn('Warning message');$this->line('Regular message');
// Tables$this->table( ['Name', 'Email'], [['John', 'john@example.com']]);
// Progress bar$bar = $this->output->createProgressBar(100);for ($i = 0; $i < 100; $i++) { $bar->advance();}$bar->finish();11. Asset Compilation
Section titled “11. Asset Compilation”Rails (Webpacker/Sprockets):
rails assets:precompilerails webpacker:compileLaravel (Mix/Vite):
# Developmentnpm run dev
# Watch for changesnpm run watch
# Production buildnpm run build
# Laravel Mix (older projects)npm run production12. Optimization Commands
Section titled “12. Optimization Commands”Laravel provides optimization commands for production:
# Optimize for production (cache config, routes, views)php artisan optimize
# Clear all cachesphp artisan optimize:clear
# Cache configurationphp artisan config:cache
# Cache routesphp artisan route:cache
# Cache viewsphp artisan view:cache
# Cache eventsphp artisan event:cache13. Package Development
Section titled “13. Package Development”Laravel:
# Create package boilerplatecomposer require spatie/laravel-package-tools
# Publish package assetsphp artisan vendor:publish --provider="VendorName\PackageName\ServiceProvider"
# Publish specific tagphp artisan vendor:publish --tag=configphp artisan vendor:publish --tag=migrations14. IDE Support
Section titled “14. IDE Support”PHP Storm / VS Code
Section titled “PHP Storm / VS Code”Both IDEs offer excellent Laravel support:
PHP Storm:
- Laravel Plugin (official)
- Laravel Idea (paid, highly recommended)
VS Code Extensions:
- Laravel Extension Pack
- Laravel Blade Snippets
- Laravel Artisan
- Laravel Goto View
- Laravel Extra Intellisense
Laravel IDE Helper
Section titled “Laravel IDE Helper”Generate helper files for better IDE autocomplete:
composer require --dev barryvdh/laravel-ide-helper
# Generate helperphp artisan ide-helper:generate
# Generate model helpersphp artisan ide-helper:models
# Generate PhpStorm metaphp artisan ide-helper:meta15. Debugging Tools
Section titled “15. Debugging Tools”Laravel Debugbar
Section titled “Laravel Debugbar”Like Rails’ debug toolbar:
composer require barryvdh/laravel-debugbar --devShows:
- Database queries (with timing)
- Route information
- Views rendered
- Memory usage
- Request/response data
Telescope
Section titled “Telescope”Laravel Telescope is like Rails’ web console but more powerful:
composer require laravel/telescopephp artisan telescope:installphp artisan migrateVisit /telescope to see:
- Requests
- Commands
- Schedules
- Jobs
- Databases queries
- Emails
- Notifications
- Cache operations
- Redis operations
Debugging tool (like binding.pry or debugger):
composer require spatie/laravel-ray<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ExampleController extends Controller{ public function index(Request $request) { // Debug with Ray ray($user); ray($request->all()); ray()->showQueries();
return view('example'); }}16. Environment Management
Section titled “16. Environment Management”Rails:
export RAILS_ENV=productionrails console -e productionLaravel:
# Laravel uses .env filephp artisan config:cache
# Check current environmentphp artisan env
# Run command in specific environmentphp artisan migrate --env=production16b. Logging Commands
Section titled “16b. Logging Commands”Rails:
# View logstail -f log/development.logtail -f log/production.logLaravel:
# View logs (default location)tail -f storage/logs/laravel.log
# Clear log (custom command or manually)# Note: Laravel doesn't have built-in log:clear# You can create a custom command or manually truncate the file::: tip Log Management
Laravel’s logging is configured in config/logging.php and supports multiple channels (single, daily, slack, etc.). Unlike Rails, Laravel doesn’t have a built-in log:clear command, but you can create one or use truncate:
# Clear log manuallytruncate -s 0 storage/logs/laravel.log:::
17. Testing Commands
Section titled “17. Testing Commands”Rails:
rails testrspecrspec spec/modelsLaravel:
# Run all testsphp artisan test
# Run specific testphp artisan test --filter=UserTest
# Run parallel testsphp artisan test --parallel
# Stop on failurephp artisan test --stop-on-failure
# With coveragephp artisan test --coverage
# PHPUnit directly./vendor/bin/phpunit
# Pest (modern alternative)./vendor/bin/pest18. Maintenance Mode
Section titled “18. Maintenance Mode”Rails (custom implementation):
# Usually custom middlewareLaravel (built-in):
# Enable maintenance modephp artisan down
# With secret bypassphp artisan down --secret="bypass-token"# Visit: /bypass-token to access site
# With custom messagephp artisan down --message="Upgrading database"
# With retry headerphp artisan down --retry=60
# Disable maintenance modephp artisan up19. Application Information
Section titled “19. Application Information”# Show Laravel versionphp artisan --version
# Show application infophp artisan about
# Show environmentphp artisan env
# List installed packagescomposer show
# Show package versionsphp artisan package:discover20. Productivity Packages
Section titled “20. Productivity Packages”Essential Laravel Packages (like Ruby gems)
Section titled “Essential Laravel Packages (like Ruby gems)”# Debugbar (development)composer require barryvdh/laravel-debugbar --dev
# IDE Helpercomposer require --dev barryvdh/laravel-ide-helper
# Telescope (monitoring)composer require laravel/telescope
# Horizon (queue dashboard)composer require laravel/horizon
# Sanctum (API authentication)composer require laravel/sanctum
# Breeze (authentication scaffolding)composer require laravel/breeze --dev
# Jetstream (advanced auth with teams)composer require laravel/jetstream
# Sail (Docker development environment)composer require laravel/sail --dev21. Laravel Sail (Docker)
Section titled “21. Laravel Sail (Docker)”Laravel Sail is like Rails with Docker:
# Install Sailcomposer require laravel/sail --devphp artisan sail:install
# Start containers./vendor/bin/sail up
# Or add alias to ~/.bashrcalias sail='./vendor/bin/sail'sail up
# Run artisan commandssail artisan migratesail artisan tinker
# Run Composersail composer install
# Run NPMsail npm installsail npm run dev
# Run testssail test
# Access MySQLsail mysql
# Access Redissail redisWrap-up
Section titled “Wrap-up”Congratulations! You’ve completed a comprehensive tour of Laravel’s developer experience tools. Here’s what you’ve accomplished:
✓ Mastered Artisan CLI - Understood how Laravel’s command-line tool compares to Rails ✓ Learned Code Generation - Generated models, controllers, migrations, views, components, and more with Artisan ✓ Explored Tinker - Used Laravel’s interactive console for development and debugging ✓ Configured Development Environment - Set up local servers with Valet or Sail ✓ Managed Databases - Ran migrations, seeders, and database inspection commands ✓ Set Up Storage - Created symbolic links for public file storage ✓ Implemented Queues - Set up background job processing with built-in queue workers ✓ Configured Scheduling - Created scheduled tasks without manual cron configuration ✓ Created Custom Commands - Built Artisan commands with rich interactions and progress bars ✓ Set Up Debugging Tools - Installed and configured Telescope, Debugbar, and Ray ✓ Configured IDE Support - Set up Laravel IDE Helper and extension recommendations ✓ Learned Hot Reloading - Understood how Laravel Mix/Vite provides HMR for frontend development
Key Takeaways
Section titled “Key Takeaways”- Familiar Yet Powerful - Laravel’s tools feel familiar to Rails developers but offer additional features
- Convention Over Configuration - Less setup, more productivity
- Built-In Everything - Queues, scheduling, and debugging tools are first-class citizens
- Rich Command Interface - Artisan commands support progress bars, tables, and interactive prompts
- Excellent Tooling - Telescope and Debugbar provide Rails-level debugging capabilities
- Docker Support - Sail makes Docker development as easy as Rails with Docker
- IDE Integration - Excellent support in PHPStorm and VS Code with proper extensions
What’s Next?
Section titled “What’s Next?”Now that you understand Laravel’s developer tools, you’ll learn PHP syntax differences in the next chapter. This will help you write Laravel code confidently when coming from Ruby.
Practice Exercise
Section titled “Practice Exercise”Try these commands to get familiar:
# 1. Create a new Laravel projectlaravel new blog
# 2. Generate a Post model with migrationphp artisan make:model Post -m
# 3. Open Tinker and create a postphp artisan tinker>>> Post::create(['title' => 'First', 'body' => 'Hello'])
# 4. List all routesphp artisan route:list
# 5. Generate a controllerphp artisan make:controller PostController --resource
# 6. Create a custom commandphp artisan make:command GreetUser
# 7. Start the development serverphp artisan serve::: tip Continue Learning Move on to Chapter 04: PHP Syntax for Rails Devs to learn PHP syntax differences. :::
Further Reading
Section titled “Further Reading”- Laravel Artisan Documentation — Official documentation for Artisan commands and custom command creation
- Laravel Tinker Documentation — Guide to using Laravel’s interactive REPL
- Laravel Telescope Documentation — Complete guide to Laravel’s debugging and monitoring tool
- Laravel Queue Documentation — Comprehensive guide to queue workers and background jobs
- Laravel Task Scheduling — Official documentation for the task scheduler
- Laravel Sail Documentation — Docker development environment for Laravel
- Laravel Valet Documentation — macOS development environment setup
- Laravel IDE Helper — GitHub repository for IDE autocomplete generation
- Laravel Debugbar — Debug toolbar for Laravel applications
- Spatie Laravel Ray — Powerful debugging tool for Laravel