Day 2 with Laravel 4

| Getting started with Laravel 4

Aim of today is to cover some more of the stuff I had done in CodeIgniter – to display some dynamic content from a database. In the CodeIgniter example, I had to manually create the database tables and enter data, but Laravel really has that covered using a technique of “migrations” and “database seeding” which I’ll get to shortly.

A lot of this stuff is based on the What’s new in Laravel 4 Tuts+ video series by Jeffrey Way, so all credit to him for providing my main source of learning for these early explorations of what Laravel 4 can do.

First steps with dynamic data

I shall return to the good old “blog” example and create an extremely simple post with title and body text. I have created a database using MAMP Pro’s built-in phpMyAdmin, and put the relevant info in app/config/database.php (database name, username, password).

First, I need to create the posts table in my database. Enter, MIGRATIONS. Migrations are a bit like version control for databases. You can do some very cool things with migrations from the command line. Here is the code to create the posts table in the database:

Looking back inside the app code, I can see Laravel has created a new file inside app/database/migrations which looks like this:

What is this all about? Well, a clue is in the Schema::create() call – I can add commands here to create fields in the ‘posts’ table of my database. A couple are already done for me, namely an auto-incrementing ID and timestamp, but I want to add “title” and “content”, which I do like this:

I’m not sure of the full extend of types you can use, but the ones above are fairly self-explanatory. $table->string('title') would create a field of type “string”. $table->timestamps() automatically creates created_at and updated_at for you. Nice.

So Laravel is ready to build my table for me. I have created the migration, but how do I actually get it to do the job and create the fields in the database? Easy – just run php artisan migrate from the command line, or, since I have created the alias art to represent php artisan, I can just run art migrate and it will build the table (fingers crossed). Looks promising:

Laravel 4 Migration

Opening the database in Sequel Pro and selecting my ‘laravel4′ database, I see:

Laravel 4 creates DB tables easily

Woo hoo! It works. Now I need to get some data in there.

Database Seeding

Laravel 4 provides some nice methods for database seeding – getting “fake data” into your DB so you can test your application. It couldn’t be easier, really.

We need to create a seed. In app/database/seeds/, there is a file called DatabaseSeeder.php. I’m going to duplicate this, and rename as PostsTableSeeder.php (following a suggested protocol by Jeffrey Way – ie TABLENAMETableSeeder), and of course add the necessary code inside to create the data in my posts table. Here’s the code once I’ve copied it and done all the renaming:

(I really do recommend using Sublime Text 2. There is a nice snippet (again by the guru Jeffrey Way) so all you do is type “seed” followed by tab and it creates the whole thing for you. It takes literally seconds to get the the point above.)

I have also updated the main DatabaseSeeder.php file as follows:

I’m not sure what Eloquent::unguard(); means, but I suppose I’ll find out in due course. The highlighted line runs our seed.

How do I now get this data into the database? Simple – back to the command line, and run php artisan db:seed, or again, because of my alias that has been set up, I can just type art db:seed, and it should stick the data in there. Terminal says ‘Database seeded!’ which is a good sign. Back to Sequel Pro to check:

Laravel 4 - DB Seeding

Result. But the date stamps look a bit weird… of course, because we didn’t supply any data! So I’m going to alter the PostsTableSeeder to include some time strings when providing the seeding data. Here’s the updated code.

I’ve deleted the rows from the database, and just ran art db:seed again – this time the time stamps look good, so I will be able to order the posts by date when I finally get the view looking good.

OK, so there is some data in the database. How do I get at it in Laravel 4? My plan is:

  1. Create a Post model to represent an entry in the posts table in database
  2. Create a BlogController controller whose index method will load the data by calling the rather magnificently simple Post::all() method and send it to a view
  3. Create the view to display the loop of posts
  4. Return the view to the browser when the user navigates to /blog/

First thing to do is update the routes.php file to tell it the plan by adding this:

In other words, call the index() method of BlogController when you are asked for /blog.

Next, the model, view and controller files.

The model can be thought of as an object that represents the table in the database. It just gives us a much more convenient way of accessing the data which will be revealed in a second. Here’s the code for my models/Post.php file:

Now the view. Inside views I’ve created a folder called blog and inside there, index.blade.php because I want to use the Blade templating engine again.

So this view file will expect some data passed in as $posts – let’s sort that in the controller which ties the model to the view:

Now, when I navigate to /blog/ I should see a loop of my posts because:

  1. routes.php has told Laravel that if someone asks for blog to load the index() method of BlogController
  2. The index() method of BlogController calls upon the Post model to return all of its records
  3. The Post model has been told (by providing the variable $table) that it is linked to the posts table in the database, and thus is able to do what it is asked – and sends back the data as requested
  4. BlogController takes that data, assigns it to ‘posts’ in an associative array and passes it to the blog/index.blade.php view
  5. This view ‘extends’ a master template, offering a ‘content’ section which renders out the loop of posts. When the master template is loaded as part of the view, it has a command to ‘yield’ a section named ‘content’… our view sticks it’s ‘content’ section in there at that time.
  6. BlogController sends back that view as the result of the original request for ‘blog’ in the browser

Does it work?

Laravel 4 - blog part 1

Yes. Phew. I’ll have to read over this tomorrow to make sure it’s not complete bollocks.