Introduction to Laravel for Ruby on Rails or Django Fans
Having developed for Ruby on Rails when it was cool, I certainly recognize who Laravel is attempting to attract by referring to a “web application framework with expressive, elegant syntax.” I don’t know PHP, but I don’t envisage the jump to be too hard. And while PHP usage is declining, it is still used on about 30 million websites — so it is worth learning. One of the advantages that “older” languages have in the era of LLMs is that developers effectively have a Rosetta stone to help with understanding.
If you’ve used Rails (or Django) then this guide should be going at your speed. Laravel is also Model-View-Controller (MVC) based, and there is an Object Relational Model built in. I can also already see references to “migrations”, so let’s go.
Go With the Herd
Laravel uses an installer, version management and environment controller called Herd. One of Ruby’s weaknesses was always versioning and environment control; I suspect I used a different combination for every project — so an all-in package with binaries is perfectly welcome.
I installed the Mac version of the Herd app on my trusty old MacBook.
They also use this to remind you that there’s a Pro version. After the install, all the relevant binaries are available in my terminal:
We learn that Laravel refers to “parked directories” that can contain projects that will be supported in Laravel by default.
First of all, let’s get a template project up and running and look at the structure:
1 |
> composer create-project laravel/laravel example-app |
What we see in our example-app directory is familiar:
(You don’t have to look far back to see where I have written about Vite, if you are wondering what that last configuration is.)
Let’s quickly serve this up with artisan before we dig into the code:
Not much feedback there!
But we see a simple front page with some pointers to docs:
At the bottom is a mention of the Laravel version, v11.26.0 — what I had above was the version of the Laravel installer.
OK, back to the code. The file that ties in the application and the server is the .env file. Since this dictates how you, as a developer, see things, you don’t want to check this in for a team. I’ll mirror a few of the important lines:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
APP_NAME=Laravel APP_ENV=local APP_DEBUG=true APP_URL=http://localhost APP_MAINTENANCE_DRIVER=file # APP_MAINTENANCE_STORE=database DB_CONNECTION=sqlite # DB_HOST=127.0.0.1 # DB_PORT=3306 # DB_DATABASE=laravel # DB_USERNAME=root # DB_PASSWORD= |
Routing
Inside the routes directory lives the web.php file that defines our application routes. These link HTTP requests with your code — so it’s rather central to any web application. There is only one route in our example, which is a php closure:
1 2 3 4 5 6 7 |
<?php use IlluminateSupportFacadesRoute; Route::get('/', function () { return view('welcome'); }); |
This links the home page with the “welcome” view. So let’s find that. Views live in the resources/view directory. Laravel uses the blade templating language, so our welcome file is welcome.blade.php. This is too ugly to list, so lets make a simple view to make sure we grok.
I’ll create the simple view file resources/views/greeting.blade.php:
1 2 3 4 5 |
<html> <body> <h1>Hello, {{ $name }}</h1> </body> </html> |
You can recognize the variable $name inserted into the HTML. If we want to see this, we need to create a route. So we’ll add the following route into web.php:
1 2 3 |
Route::get('/greeting', function () { return view('greeting', ['name' => 'TheNewStack']); }); |
This should allow us to resolve the url /greeting while showing the greeting. This worked immediately…
…with the expected confirmation of the call in my still-running local server terminal tab.
Of course, we also want to work with the other bits in MVC — namely, models and controllers.
Seeding
If we look in the database directory, we can see that there are three migrations, along with a SQLite database. Using my limited SQLite skills, I could see that the migrations have taken place, but there is no user data as yet.
This is what the user table looks like from SQLite:
1 2 3 4 5 6 7 8 9 10 |
CREATE TABLE IF NOT EXISTS "users" ("id" integer primary key autoincrement not null, "name" varchar not null, "email" varchar not null, "email_verified_at" datetime, "password" varchar not null, "remember_token" varchar, "created_at" datetime, "updated_at" datetime); CREATE UNIQUE INDEX "users_email_unique" on "users" ("email"); |
There is no actual data, however. Within the seeders directory lies this code, clearly designed to add one user entry using the user model’s factory:
Using the server tool, I ran this:
Running the select statement again in SQLite proved that data had indeed been added.
There is a user model file, but the code just nods through the database definition that we can already see from the user schema.
So we have a user model and some data. We need to add a controller, as none is present in the example. Let’s try something simple. First, we can create the file itself using artisan:
I can then put some example code into that file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace AppHttpControllers; use AppModelsUser; use IlluminateViewView; class UserController extends Controller { /** * Show the profile for a given user. */ public function show(string $id): View { return view('user', [ 'user' => User::findOrFail($id) ]); } } |
Then, we can add a route:
1 2 3 4 |
use AppHttpControllersUserController; ... Route::get('/user/{id}', [UserController::class, 'show']); |
Similarly, I’ll ask artisan to create a user view:
I’ll put enough in it, based on what I saw in the seeder:
1 2 3 4 5 6 7 8 9 |
<div> <html> <body> <h2>User {{$user->id}}</h2> <h3>Name: {{$user->name}}</h3> <h3>Email: {{$user->email}}</h3> </body> </html> </div> |
We get what we expect immediately:
Conclusion
Now this all goes to show that Laravel is indeed sufficiently similar to Rails that you can just use it. But take time to read about the differences; most agree that Laravel is more scalable, for example.
Much as I love Ruby, it has quite a deep meta-programming model that is not easy to pick up. Laravel is newer and has had time to observe the web landscape. Either way, it is definitely worth trying it out if you are looking for an established web platform for a dedicated project.