Words and things...

Custom Migration Columns in Laravel 5 #

PHP  Laravel 5  Migrations  Published 30th June 2015 and last updated 1 year ago

Intro


One thing I always find myself repeating in projects is the ability to easily keep track of who created or updated a record.


I'd have to make sure I added a created_by and updated_by column to each table in my migrations and set the correct data types. I'd then have to add the relationships to each of my models. The process quickly became repetitive so I decided to automate it a little.


Creating our Blueprint


The easiest way to deal with the migrations is to create a custom column type which is relatively straight forward.


<?php 
// app/Database/Schema/Blueprint.php

namespace App\Database\Schema;

class Blueprint extends \Illuminate\Database\Schema\Blueprint
{
public function authors()
{
$this->integer('created_by')->unsigned()->nullable();
$this->integer('updated_by')->unsigned()->nullable();

$this->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$this->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
}
}

Here we're defining a new Blueprint and a column type called authors where we'll store the unique user ids of the people who created or updated the records. We're also defining a foreign key for each to make sure in the event a user is deleted, our columns will be set to NULL.


Resolving our Blueprint


Next we need to resolve our new Blueprint so it's accessible within our migrations.


<?php 
// app/Database/Migration.php

namespace App\Database;

use Illuminate\Support\Facades\DB;
use App\Database\Schema\Blueprint;

class Migration extends \Illuminate\Database\Migrations\Migration
{
protected $schema;

public function __construct()
{
$this->schema = DB::connection()->getSchemaBuilder();

$this->schema->blueprintResolver(function ($table, $callback) {
return new Blueprint($table, $callback);
});
}
}

Now we're ready to use it. Let's use a simple articles table as an example.


<?php
// database/migrations/create_users_table.php

use App\Database\Migration;
use App\Database\Schema\Blueprint;

class CreateArticlesTable extends Migration
{
public function __construct()
{
parent::__construct();
}

/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->schema->create('articles', function (Blueprint $table) {
$table->integer('id', true)->unsigned();
$table->string('title');
$table->text('body');
$table->authors();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$this->schema->dropIfExists('articles');
}
}

Notice we're using our new App\Database\Schema\Blueprint and not the default Illuminate\Database\Schema\Blueprint here. We're then calling the parent constructor which resolves our Blueprint and gives us access to the authors() method.


Finally, we can create a base Model to always implement the creator and updater relationships.


<?php 
// app/Model.php

namespace App;

class Model extends \Illuminate\Database\Eloquent\Model
{
public function creator()
{
return $this->belongsTo('App\User', 'created_by', 'id');
}

public function updater()
{
return $this->belongsTo('App\User', 'updated_by', 'id');
}
}

Now if you extend this base model, you'll have access to the creator and updater user information.


A Laravel 5 API Boilerplate #

PHP  Laravel 5  API  Boilerplate  Published 20th June 2015 and last updated 1 year ago

Intro


If like me you concentrate mainly on Backend Web Development, it's safe to assume you've probably built your fair share of APIs. While the process can be fun, it can also quickly become tedious when having to repeat familiar CRUD tasks.


After all, the likelihood is you'll have multiple data stores which you'll want to be able to create, delete, update and fetch records for.


Luckily for the lazy amongst us, a lot of these things can be taken care of using a Repository Pattern.


Interfaces/Contracts


Firstly, let's set-up our Interfaces (or Contracts) which our Repositories must abide by.


I place my contracts in app/Contracts to match Laravel's framework directory structure.


<?php
//app/Contracts/Repository.php

namespace App\Contracts;

use App\Model;

interface Repository
{
public function create(array $attributes = []);

public function update(Model $model, array $attributes = []);

public function delete($id = 0);

public function getAll($start = 0, $limit = 0);

public function getById($id = 0);
}

As you can see, this will act as our base repository interface and defines the standard methods you would expect an API to perform.


Now we can write our actual repository classes and any additional none standard methods they may perform. For example besides the functionality above, a user repository may have a method for finding an account by email. Or you may want to be able to delete an article by slug.


Here's how the above examples would look. Remember, we don't need to define the create, update or delete methods again as these are taken care our by the base repository interface above.


<?php 
//app/Contracts/UserRepository.php

namespace App\Contracts;

interface UserRepository
{
public function getByEmail($email = '');
}

<?php
//app/Contracts/ArticleRepository.php

namespace App\Contracts;

interface ArticleRepository
{
public function deleteBySlug($slug = '');
}

Repositories


Once our interfaces are in place, we can start implementing them within our actual repository classes. You can place these anywhere within your app directory, but I personally prefer app/Repositories.


Let's start with our base Eloquent repository, which implements our repository contract.


<?php
//app/Repositories/EloquentRepository.php

namespace App\Repositories;

use App\Contracts\Repository;
use App\Model;

class EloquentRepository implements Repository
{
protected $repository;

public function __construct(Model $repository)
{
$this->repository = $repository;
}

public function create(array $attributes = [])
{
$record = $this->repository->create($attributes);
if (! $record) {
return false;
}

return $record->fresh();
}

public function update(Model $model, array $attributes = [])
{
foreach ($attributes as $key => $value) {
$model->{$key} = $value;
}

$model->save();

return $model->fresh();
}

public function delete($id = 0)
{
$record = $this->getById($id);

if (! empty($record)) {
return $record->delete();
}

return false;
}

public function getAll()
{
return $this->repository->get();
}

public function getById($id = 0)
{
return $this->repository->find($id);
}
}

So there are our generic CRUD methods taken care of. These perform the standard operations for all of our repositories, whether it's creating a User, deleting an article, or updating a Comment.


Let's now create our Eloquent User Repository by extending our base Eloquent Repository.


<?php 
//app/Repositories/UserRepositoryRepository.php

namespace App\Repositories;

use App\Contracts\UserRepository;
use App\User;

class EloquentUserRepository extends EloquentRepository implements UserRepository
{
public function __construct()
{
parent::__construct(new User());
}

public function getByEmail($email = '')
{
return $this->repository->query()->where('email', $email)->first();
}
}

Notice we're passing the Eloquent User model through to our parent Eloquent Repository in the constructor. We're then simply implementing the getByEmail() method we defined earlier.


Controllers


Now we've created our repositories, it's time to generate our controllers which will be used to call our repository methods.


Just like with our repositories, we'll start by defining a base controller.


<?php 
//app/Http/Controllers/APIController.php

namespace App\Http\Controllers;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Bus\DispatchesJobs;
use App\Http\Controllers\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use App\Contracts\Repository;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class APIController extends BaseController
{
use DispatchesJobs, ValidatesRequests;

protected $request;
protected $repository;

public function __construct(Request $request, Repository $repository = null)
{
$this->request = $request;
$this->repository = $repository;
}

protected function getRules()
{
return [];
}

public function create()
{
$this->validate($this->request, $this->getRules());

$new = $this->repository->create($this->request->input(), $this->relations);

if (! $new) {
return response([], 422);
}

return response($new, 201);
}

public function update($id)
{
$this->validate($this->request, $this->getRules($id));

$record = $this->repository->getById($id);

if (empty($record)) {
return response([], 404);
}

return response($this->repository->update($record, $this->request->input()));
}

public function delete($id)
{
$deleted = $this->repository->delete($id);

if (! $deleted) {
return response([], 404);
}

return response([], 204);
}

public function index()
{
return response($this->repository->getAll());
}

public function getById($id)
{
$record = $this->repository->getById($id);

if (empty($record)) {
return response([], 404);
}

return response($record);
}
}

You should now be able to see a pattern between our base repository and base API controller. The create method on our controller calls the create method on our repository, the update calls the update and so on and so forth.


Finally, we're now ready to create our User Controller which will extend our Base API Controller.


<?php 
//app/Http/Controllers/UserController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Contracts\UserRepository;

class UserController extends APIController
{
public function __construct(Request $request, UserRepository $repository)
{
parent::__construct($request, $repository);
}

protected function getRules($id = 0)
{
return [
'name' => ! empty($id) ? 'sometimes|' : '' . 'required|min:2|max:255',
'email' => ! empty($id) ? 'sometimes|' : '' . 'required|email|unique:users,email,' . $id,
'is_admin' => 'sometimes|required|boolean',
];
}

public function getByEmail($email)
{
return response($this->repository->getByEmail($email)):
}
}

With a few lines of code, our User Controller now has all the API CRUD methods available to it. We simply call the constructor on the API Controller and pass through our User Repository for it to use.


Don't Forget


Add any repositories you create to the service provider. Here's how my app/Providers/AppServiceProvider.php file looks.


<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

protected $services = [
'App\Contracts\Repository' => 'App\Repositories\EloquentRepository',
'App\Contracts\UserRepository' => 'App\Repositories\EloquentUserRepository',
];

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
}

/**
* Register any application services.
*
* This service provider is a great spot to register your various container
* bindings with the application. As you can see, we are registering our
* "Registrar" implementation here. You can add your own bindings too!
*
* @return void
*/
public function register()
{
foreach ($this->services as $contract => $service) {
$this->app->bind($contract, $service);
}
}

}

And that's it


Now you have a base repository and controller which will hopefully save you a lot of time in the future, not to mention frustration!


It's also a great way to implement other standard API features such as limiting or offsetting results.


If you have any questions or suggestions, feel free to ask.