archtechx / tenancy

Automatic multi-tenancy for Laravel. No code changes needed.
https://tenancyforlaravel.com
MIT License
3.58k stars 425 forks source link

Synced resources between tenants are not linked #561

Closed DenisaHalmaghi closed 3 years ago

DenisaHalmaghi commented 3 years ago

Describe the bug

Synced resources between tenants:

When I create a user in the tenant database, even if that user already exists in the central database, it will try to create it again in the central database. The same thing happens when i update a user in the tenant databse.

Furthermore, the global_id for the user in the tenant database is does not match the one i enter in the create function , it is generated automatically.

Also, i do not see any entry in the tenant_user pivot table which would link the global user and the users in the tenant databases.

Steps to reproduce

the tenant user migration:

Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('global_id');
            $table->string('name');
            $table->string('email')->unique();
            $table->unsignedInteger('current_company_id')->nullable();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->unique('global_id');
            $table->rememberToken();
            $table->timestamps();
        });

the central user migration:

 Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('global_id');
            $table->string('name');
            $table->string('email')->unique();
            $table->unsignedInteger('current_company_id')->nullable();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->unique('global_id');
            $table->rememberToken();
            $table->timestamps();
        });

the User model prototype:

class User extends Model implements Syncable
{
    use HasFactory, Notifiable, ResourceSyncing;
    ....
}

the CentralUser model prototype:

class CentralUser extends Model implements SyncMaster
{
    use ResourceSyncing, CentralConnection;

    ....
}

The other methods and declarations and migrations (tenant-user) are taken from the example implementation

Steps:

  1. open artisan tinker
  2. $user = App\Models\CentralUser::create([
    'global_id' => 'acme',
    'name' => 'John Doe',
    'email' => 'john@localhost',
    'password' => 'secret',
    ]);

3.Having previously seeded/ created a tenant:

tenancy()->initialize($tenant);

4.

$user = User::create([
    'global_id' => 'acme',
    'name' => 'John Doe',
    'email' => 'john@localhost',
    'password' => 'secret',
]);

This should throw an error :

Integrity constraint violation: 1062 Duplicate entry 'john@localhost' ...

So the user is being created again in the central database ... The same goes for 5.

$user->update([
    'name' => 'John Foo', 
    'email' => 'john@foreignhost',
]);

Expected behavior

I expect that when a user which has the same "global id" with another user in the central databse is created in the tenant database, it would be linked to the one in the central database Furthermore, when said user is updated in the tenant database, a new used should not be created in the central database, but the existing one should be updated.

Setup

stancl commented 3 years ago

Can you look at the ResourceSyncingTests and tell me what use case is not covered? I don't have the time to read through your entire setup but what you're describing in "expected behavior" should be working.

DenisaHalmaghi commented 3 years ago

I don't think you have a test for it.

I noticed that even though i supply a global id for the user created in the tenant database, it is still generated using id generator, so it won't match the one in the central database, which is probably why it is trying to create that user again in the central database. So maybe a test like

public function global_id_is_NOT_generated_using_id_generator_when_its_supplied()
{

}

would do the trick.

Please let me know what you think.

DenisaHalmaghi commented 3 years ago

Ok.. so apparently global id was not inside fillable and yet no Mass Asignment error was thrown and that's why a uid was attributed.

Closing this.

abanghendri commented 3 years ago

Hello, I still face the same issue, please let me know how to fix that issue

victoriaABClogistica commented 1 year ago

Me di cuenta de este error , Para solucionar eso tienen que hacer que el Id del usuario sea el mismo en todos los tenancy

  public function getSyncedAttributeNames(): array
    {
        return [
            'id',
            'name',
            'password',
            'email',
        ];
    }