laravel4

I started using Laravel 4 for testing, hobby projects, and actual work (ha!) a couple of months back and was genuinely excited about the upgrades as well as features I wasn’t aware of from previous versions as well. So here goes :)

Composer and Autoloading

If you’ve worked with L3, you’ll remember that there was no real autoloading and that bundle installing took place via Artisan and through a “market place” (so to speak) on the Laravel site. Things changed drastically for the better in L4. Not that the system was bad, it was actually quite good since many Packagist bundles were converted to Laravel style of coding, but it was limited. This is where Composer comes into play. Composer is a modern dependency manager, installer, and class autoloader. Basically, it allows you to specify a JSON file with different packages and run the Composer.phar file to download/update those packages.

Not only that but if you remember L3, the “autoloading” took place via either dropping new libraries into the /libraries folder or by specifying a new folder in one of the start files (can’t remember which one). Things are much more concise now.

So what do you do? Open your composer.json file in your install (you may have even installed Laravel this way). You’ll see an “autoload” section. Here:

   "autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php"
        ]
    },

In the Autoload section, you can specify any new folders you want Composer to look through and add to its autoload. If you write a library for some specific parsing of yours, you can add it to a custom folder. Let’s call it “parsers” and add it to the laravel folder. Add the directory to the composer.json file:

   "autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php",
            "parsers"
        ]
    },

By running the following command:

php composer.phar install

Your parser class is added to the global scope. You can pretty much call on it wherever you want in the application. Composer, however, also lets you install various packages and specify them as dependencies. Let’s say you want to add a Markdown parser into your app. You’ll just modify the “require” part of the JSON file (composer.json):

   "require": {
        "laravel/framework": "4.0.*"
        "dflydev/markdown" : "1.*"
    },

By running install again, the package will be downloaded and installed into the /vendor directory. Neat, right? :) Read more about the tool since it’s used in the same manner in all composer-friendly projects.

Override default fields

You can override default ORM fields such as “created_at” and “updated_at” by re-setting the constant governing them in your model. So for example, in your user.php model, you can do:

const CREATED_AT = 'creation_date';

if your equivalent of “created_at” is “creation_date”. You’ll still pull the info for it by using $user->creation_date; however, it will now behave the same way as the native created_at column would. If you specify an updated column this way, it will get updated with “touch” just like updated_at would.

Easily create RESTful and Resource Controllers

You can easily create a controller framework via an Artisan command which creates a “resource” controller. A controller meant to be routed like so:

Route::resource('path', 'someController');

and be used in a RESTful manner. Very useful for API creation.

There are also “resource” controllers that bind in a similar way except they are based on common REST conventions:

resource-controller

 

Pretty simple and useful stuff :)

Remember, Remember

To cache your query results, you can simply add a remember(100) clause to remember the results of your query for a specified number of minutes like so:

User::where('active', '=', '1')->remember(100)->get();

This will remember all users with the ‘active’ column marked as ’1′ for a 100 minutes. Whenever you use this query, it will not contact the database but use cache instead. VERY useful. Imagine creating a complex, giant beast of a query and instead of having to run it several times over the course of a user’s request, you can simply cache it! :)

Scopes

You can easily create your own function to add to a query in your model. For example, whenever you call for your latest comments, you might want to call the associated users and perhaps the comments’ upvoters (people that upvoted it, liked it, or 1 plussed it). Given that you already have the relationships setup you could create a function in your model:

public function scopeFullComments($query){ return $query->with('upvoters', 'user'); }

and call it in your query like so:

Comment::fullComments()->where('parent', '=', '55')->get();

This way, instead of having to memorize all the relationships you require, you can create scope functions that help you out. You could create one for anything. If you often need this “fullComment” information, create this function.

You can create any custom functions to do anything including “where” statements, and others so that you don’t have to memorize often-used query parameters.

Passing Variables By View

You can pass specific information whenever a specific view is created. For instance, everyone one of your pages that uses your “main” template, or whatever else, may need to know if a user is logged in. Instead of creating filters or specific logic per route, you can inject this logic into your view directly.

In my case, I’m building a website that will show a list of main categories as part of a menu so every time I call my regular template, I need to have my $categories model fully saturated and ready to be parsed. I can either include this logic directly in my blade file (not a good idea!), via route (via every single route, bad idea), or by using a view composer.

Here’s how to make it:

Create a folder where you’d like to store your view composers (I created viewComposers under laravel/app)

Create a file mirroring the name of the class you’ll use and add the following code:

<?php
//pick a class name
class basicComposer {

    public function compose($view)
    {
        //getting data
        $mainCategories = Category::->remember(600)->get();
               //passing it off
        $view->with('mainCategories', $mainCategories);
    }
}

Notice that I’m using the aforementioned remember() function to store the category setup for 600 minutes, long enough and short enough at the same time. Whenever I solidify my usage of categories, I’ll either up the number or use a different method of loading them.

Great, pick up routes.php and let’s bind the composer to the view:

View::composer('templates.main', 'basicComposer');

You’re almost done, now you just need to add your viewComposers folder into composer.json file in the laravel folder:

   "autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php",
            "app/viewComposers"
        ]
    },

Last thing, let’s redo our autoload so that laravel is aware of our basicComposer class.

php artisan dump-autoload

That’s it! :) You can read about it in Laravel’s docs but there’s really not that much more other than what I’ve just said.

Databases and Seeding

I’ve actually written about this one but here’s a quick overview:

  • Laravel migrations allow you to “version” changes in your database and make updates that you can easily rollback. What do I mean? You can create a “migration” (a php file) that specifies when you want to add a column, add a table or whatever else. You also specify what you want to do to “roll back”. For example, dropping a table.
  • Seeders allow you to seed initial data into your tables. This is great for testing environments where you can seed testing data.
  • Artisan commands allow you to completely wipe and rebuild your database with one command. Again, wonderful for testing environments, installations, and resets.
  • It’s all super easy to do.

Go ahead and read my article on the topic but outside of that, that’s the gist of it. I was excited to learn how in-depth Laravel’s migration/seeding capabilities are and this kind of stuff make it easier to setup a working test environment with Vagrant or wherever else.

 What else?

This is as far as I’ve gotten with Laravel 4. It’s a very neat framework and it’s definitely a HUGE step up from L3 (which was amazing as hell already). What’s even better is the fact that I had no trouble whatsoever setting up a Vagrant testing environment for L4 due to its neat migrations and seeding as well as Composer usage.

If you know of any other sweet features, let me know and I’ll add them to the list :)

Reader Suggested:

Fluent/Eloquent Lists

When using Fluent/Eloquent, you can use the “lists” method to quickly build an array of data that can easily populate the Form::select() HTML helper.

$categories = Categories::orderBy('type')->lists('type', 'id');
Form::select('category_id', $categories );

The resulting array will populate the option value as the “id” field from the DB and the “type” will populate what value appears in the drop down. For example: <OPTION value=”id”>type</OPTION> So you can adapt that pattern to whatever you want the resulting array to look like. In this example, the array is indexed by my id column with the value of each “type”.

(source)

Query Dump

DB::listen(function($sql, $bindings, $time)
{
    var_dump($sql);
    var_dump($bindings);
});

Put this in your App::before filter and you’ll get a nice, ugly dump of the queries being run against your database.

This is great when you’re getting started with Eloquent and just want to know what the hell the actual SQL looks like.

(source)