hipsterjazzbo / Landlord

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

Modify tenant id in after middleware? #52

Closed inctor closed 7 years ago

inctor commented 7 years ago

Hey,

It seems like it's not possible to modify the Tenant ID after it's been set once.

Currently we're setting in a Scope Middleware, that's globally applied, and it works perfectly.

But we have a few instances where we'd like to change/modify the Tenant ID to be something else, if we need to run artisan commands or other console related commands.

This is what i've tested with:

`\DB::enableQueryLog();

    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));

    \Landlord::disable();
    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));

    \Landlord::removeTenant('company_id');
    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));

    \Landlord::addTenant('company_id',123);
    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));

    \Landlord::addTenant('company_id',123);
    User::allTenants()->whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));

    dd( \DB::getQueryLog() );`

And this is the response i'm getting:

{"company_id":71} {"company_id":71} [] {"company_id":123} {"company_id":123} array:5 [ 0 => array:3 [ "query" => "select from users where activated = ? and users.company_id = ? and users.deleted_at is null" "bindings" => array:2 [ 0 => 1 1 => 71 ] "time" => 0.72 ] 1 => array:3 [ "query" => "select from users where activated = ? and users.company_id = ? and users.deleted_at is null" "bindings" => array:2 [ 0 => 1 1 => 71 ] "time" => 0.82 ] 2 => array:3 [ "query" => "select from users where activated = ? and users.company_id = ? and users.deleted_at is null" "bindings" => array:2 [ 0 => 1 1 => 71 ] "time" => 0.44 ] 3 => array:3 [ "query" => "select from users where activated = ? and users.company_id = ? and users.deleted_at is null" "bindings" => array:2 [ 0 => 1 1 => 71 ] "time" => 0.49 ] 4 => array:3 [ "query" => "select * from users where activated = ? and users.deleted_at is null" "bindings" => array:1 [ 0 => 1 ] "time" => 0.42 ] ]

As seen, the Tenant ID is the same for all of them, except after i've called "allTenants()", it correctly removed the tenant-scope, but that's not what i want to achieve.

Is this an issue with this package, or something deeper in Eloquent's way of handling the global scopes?

In addition to this, Disable() does not seem to make any difference at all either.

inctor commented 7 years ago

Some clarification. It's possible to modify the Tenant ID if you call bootBelongsToTenants() every single time you need to change the TenantID, it sadly does not happen automatically.

Is it possible to change this functionality around, to be more similar to how it was done in the AURA package? Where it just applied the "where" to the Eloquent Builder.

inctor commented 7 years ago

In regards to this issue, the problem still exists, but we've worked around it, and went through our callstack, and made certain nothing can get booted before it's needed and the middleware scope has run.

Also had to implement the change from this PR to fix the other issue. https://github.com/HipsterJazzbo/Landlord/pull/53

MrRio commented 7 years ago

I have an issue where the app already boots User model, calling bootBelongsToTenants() after doesn't seem to fix it.

inctor commented 7 years ago

@MrRio , i'd advise doing "throw new ErrorException" in the boot-method of your user object, and trace through the call stack to see where the model is being booted BEFORE the middleware is booted.

Possibly even adding some Log::info() in the middleware doing the scope, and the boot-method, so you can verify it's not being booted beforehand.