hipsterjazzbo / Landlord

A simple, single database multi-tenancy solution for Laravel 5.2+
MIT License
614 stars 138 forks source link

Where to run addTenant #56

Closed HelgeSverre closed 7 years ago

HelgeSverre commented 7 years ago

The documentation does not make it quite clear where you would put the call to Landlord::addTenant(), althought I assume in some sort of middleware, however It would be great if a couple of examples of real world usage would be placed in the docs.

haydndup commented 7 years ago

I'd agree with this - would love some examples.

dmarklund commented 7 years ago

I have always inserted it in the middleware.

gandra commented 7 years ago

I would also like to see examples. I have database where some tables do not have tenant_id. How to manage this situation?

haydndup commented 7 years ago

Hi ganrda,

For your existing tables, you'd need to add a migration to insert a tenant_id column. For example:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTenantsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tenants', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::table('users', function (Blueprint $table) {
            $table->integer('tenant_id')->unsigned()->nullable();

            $table->foreign('tenant_id')->references('id')->on('tenants')
                ->onUpdate('cascade')->onDelete('cascade');
        });

    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropForeign('users_tenant_id_foreign');
            $table->dropColumn('tenant_id');
        });

        Schema::dropIfExists('tenants');
    }
}

For an example, I created the following middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Auth;
use Landlord;

class ScopeMultiTenant
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (Auth::check()) {
            $tenantId = Auth::user()->tenant_id;

            if($tenantId != null) {
                Landlord::addTenant('tenant_id', $tenantId);
            }
        }

        return $next($request);
    }
}

Then all you need to do is add it to your web and/or API middleware configuration in the Kernel.php file.

Beware, you cannot add it to the global middleware, as PHP sessions are not yet instantiated, and hence it is impossible to check which user is currently logged in. Sessions are only started later in the Kernel boot process.

hipsterjazzbo commented 7 years ago

I've been as clear as I can, but unfortunately it really depends on the nature of your application. In most cases, a middleware is okay, but in others it won't work. I'll try to work out some common examples though.