Wednesday, February 19, 2014

Laravel 4: Model Hydrate

Problem:
While converting some older Laravel code, I ran into an issue where the hydrate method had been removed. My usage was similar to this:

$raw_result = DB::query(...);
$hydrated_models = Model::hydrate(new Model(), $data);


Solution:
While the method may have been removed, there are other methods which can be used to achieve the same outcome. One such method is the newFromBuilder method which can be used as follows:

$raw_result = DB::select(...);
$collection = new \Illuminate\Database\Eloquent\Collection();
foreach ($raw_result as $raw_obj)
{
     $model = new Model();
     $collection->add($model->newFromBuilder($raw_obj));
}

If you would like to abstract this process into a static method on the model. You can do so by creating a BaseModel extending Eloquent in which other models you want to have the hydrate method can extend. 

For example: 

use Illuminate\Database\Eloquent\Collection;
class BaseModel extends Eloquent
{

    /**
     * Hydrate method
     * 
     * @param array $data
     * @return Illuminate\Database\Eloquent\Collection
     */
    static public function hydrate($data)
    {
        // get calling class so we can hydrate using that type
        $klass = get_called_class();
        
        // psuedo hydrate
        $collection = new Collection();
        foreach ($data as $raw_obj)
        {
            $model = new $klass;
            $collection->add($model->newFromBuilder($raw_obj));
        }
        return $collection;

    }
}

class User extends BaseModel
{
    /* ... */
}

// Usage of hydrate
$user_collection = User::hydrate($data);

Along with Model::hydrate, the DB::query method no longer exists. See more changes happening when upgrading from Laravel 3 to Laravel 4.

No comments: