Comments (16)
A much cleaner solution, and seems to be working fine!
Thanks!
from landlord.
Sorry guys, I haven't had much time to dig into this, but I won't be putting this into the package. Being able to deal with the individual tenancies separately is a core function of Landlord.
At some point when I have time to really dig into it, I'll have to figure out why that solution even works — why would it fail when applying 2 scopes, but not when applying 1? That's the real issue as far as I can see.
from landlord.
Seems to be a bit ugly solution but if works for you is enough. For sure it will help other users.
I'm remembering that the problem is that the library applies a global scope on boot by each tenant. Maybe It can be fixed if applies a global scope for all tenants.
Something like (I didn't test it):
public function applyTenantScopes(Model $model)
{
if (!$this->enabled) {
return;
}
$model->addGlobalScope('landlord-scope', function (Builder $builder) use ($model) {
$this->modelTenants($model)->each(function ($id, $tenant) use ($builder, $model) {
$builder->where($model->getQualifiedTenant($tenant), '=', $id);
});
});
}
When current code is ( https://github.com/HipsterJazzbo/Landlord/blob/master/src/TenantManager.php#L118 ):
public function applyTenantScopes(Model $model)
{
if (!$this->enabled) {
return;
}
$this->modelTenants($model)->each(function ($id, $tenant) use ($model) {
$model->addGlobalScope($tenant, function (Builder $builder) use ($tenant, $id, $model) {
$builder->where($model->getQualifiedTenant($tenant), '=', $id);
});
});
}
from landlord.
I managed to get it to work by creating the following middleware and adding it to the web
middleware group in Kernel.php
:
public function handle($request, Closure $next)
{
if (Auth::check()) {
foreach (Auth::user()->getTenantColumns() as $tenant_scope) {
Landlord::addTenant($tenant_scope, Auth::user()->{$tenant_scope});
Landlord::applyTenantScopes(Auth::user());
}
}
return $next($request);
}
I think it has something to do with the user model being booted before the global scope is being applied.
If I change the above code to use the authenticated user directly in the addTenant
method, it doesn't work:
public function handle($request, Closure $next)
{
if (Auth::check()) {
foreach (Auth::user()->getTenantColumns() as $tenant_scope) {
Landlord::addTenant(Auth::user());
Landlord::applyTenantScopes(Auth::user());
}
}
return $next($request);
}
from landlord.
Hi @mariomka!
I'm having this same issue. Did you manage to solve it?
Also, how are you using $landlord->applyTenantScopes(new Model);
? Could you provide an example with the code you posted above?
Thanks!
from landlord.
@fgilio I didn't find a solution.
Finally I wrote a simple multi-tenancy system for my project.
I don't remember exactly. I think that you can call Landlord::applyTenantScopes($account);
before get the count to fix this simple test.
Good luck!
from landlord.
Hi @mariomka, thanks for the reply!
I was actually editing the comment with my temporary solution:
I added this method to the model and I call it when I need to re apply the scope with a different ID. But of course, I was already doing Landlord::addTenant($tenant);
on start and Landlord::removeTenant($tenant);
on finish (which I think is not necessary, as it resets when you add a new tenant of the same type) of the loop.
public static function reApplyTenantScopes()
{
static::$landlord->applyTenantScopes(new static());
}
So in the DB seeder I call it like this before executing a query:
App\MyTenantScopedModel::reApplyTenantScopes();
I just feels too hacky for my like, but seems to be working ok. I'll keep testing it and update here if I find that this brings some kind of problem.
I hope it helps other having similar issues, I can't believe the amount of time I spent debugging this.
from landlord.
Nice! I didn't have time to try. Maybe I'll make a pull request when I have time, Right now I don't know if the change breaks anything.
PD: Feel free to make a pull request if you want.
from landlord.
There are a few things I'm aware of (just generally) that don't play nice between Eloquent boot functionality and tests, because the framework doesn't re-boot between each test. If someone finds a good solution to this issue I'll consider it.
from landlord.
Didn't do the pr because I didn't have time to do formal tests. But, I'm using @mariomka solution since then and It's working flawlessly.
from landlord.
Unfortunately, that breaks some pretty important functionality for the library, namely that you can no longer run queries without a single tenant scope while leaving the others on:
// Will not scope by 'tenant_id', but will continue to scope by any other tenants that have been set
ExampleModel::withoutGlobalScope('tenant_id')->get();
from landlord.
What if we make this optional?
It could be like having a master switch that dictates how the library will behave, and the default would still be the current behaviour.
Honestly, I'd like to continue using the official library and not a fork.
from landlord.
Why is there no solution in order to work together globally?
as brainstorming,
If requested this method
ExampleModel::withoutGlobalScope('tenant_id')->get();
Stop work for this method
applyTenantScopes(Model $model)
from landlord.
This is absolutely to do with the way laravel runs tests. Every mode is booted once for the whole test run. This means that things can get out of whack on any test after the first one — this is the case for any global scope on an eloquent model, not just Landlord.
Unfortunately, I don't think there's much that can be done about it from this package. I've opened PRs in the past to fix it in the framework, but Taylor has declined them. Perhaps that'd be the better strategy?
from landlord.
public function handle($request, Closure $next)
{
if(auth()->check())
{
$tenantId = auth()->user()->tenant_id;
Landlord::addTenant('tenant_id', $tenantId);
Landlord::applyTenantScopes(auth()->user());
}
return $next($request);
}
I just added this as my middleware and it worked somehow. I am not sure
from landlord.
Hey guys, does anyone have a solution on how to test queries being scoped (testing through http, not unit tests) without explicitly calling applyTenantScopes()
for each scoped model in the middleware?
from landlord.
Related Issues (20)
- how do we get current talnet?
- Still active? HOT 9
- Preserve tenant ID when executing queued job HOT 1
- Scope is not applied when model is instantiated via dependency injection within controller HOT 1
- Laravel 5.8 Support HOT 1
- Tenant Breaks when used with ModelObserver
- Example Middleware for Laravel 5.5 HOT 2
- BelongsToTenant not working on user model HOT 2
- WIth multiple tenants Landlord uses first tenant id for the other tenant scopes HOT 3
- Class landlord not found - Laravel 5.5 HOT 1
- Tenants getting mixed up HOT 1
- Multitenant not working with User model HOT 4
- Make Macroable
- Creating new Tenant scoped Models HOT 3
- Support Laravel 5.6 HOT 4
- Call allTenants() on a relationship HOT 1
- not working
- I am trying to install in Laravel 5.6 HOT 5
- Landlord does not work in Laravel 5.6 HOT 1
- Can't set $tenantColumns in model
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from landlord.