Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registration flow question #23

Closed
dambridge opened this issue May 26, 2020 · 9 comments
Closed

Registration flow question #23

dambridge opened this issue May 26, 2020 · 9 comments

Comments

@dambridge
Copy link
Sponsor

dambridge commented May 26, 2020

Looks great, and so far so good. Cheers!

I've got an initial setup in which a user registers, a tenant is created and its db created. Wondering your thoughts on best approach to complete the process.

I'm thinking of dispatching a job for seeding the tenant database (using Artisan::call) like so:

Artisan::call('tenants:artisan migrate --seed', [
            '--tenant' => [$this->tenant->id],
        ]);

and inserting the User. I understand I can make jobs tenant-aware, but my auth routes are outside the tenant subdomain. Can I still use makeCurrent() here somehow? Or do I need to manually pass the new Tenant Id directly to the job at this stage?

@dambridge
Copy link
Sponsor Author

dambridge commented May 26, 2020

Hmm, I think I overlooked the simplicity of $tenant->makeCurrent().

That said, still banging on correct syntax for the Artisan call...

Artisan::call('tenants:artisan', [
            'migrate' => true,
            '--seed' => true,
            '--tenant' => [$this->tenant->id],
        ]);
Symfony\Component\Console\Exception\CommandNotFoundException: The command "tenants:artisan migrate --seed" does not exist. in /home/vagrant/code/sites/troovy/vendor/laravel/framework/src/Illuminate/Console/Application.php:181

@dambridge
Copy link
Sponsor Author

dambridge commented May 26, 2020

Update. This seems to run properly:
Artisan::call('tenants:artisan "migrate --seed" --tenant=' . $this->tenant->id);

However, I now get this:

Next Doctrine\DBAL\Driver\PDOException: SQLSTATE[HY000] [1049] Unknown database 'a0eb5d78-9c85-48ae-8d21-4981a4d93643' in /home/vagrant/code/sites/troovy/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:31

I have a tenant prefix of 'tenant_' on tenant databases. Does the Artisan command just look at $tenant->database perhaps, without adding prefix? Checking...

Update. Tried inserting 'tenant_' . Str::uuid() instead of just UUID into Tenants db. Same error:

PDOException: SQLSTATE[HY000] [1049] Unknown database 'tenant_2e116d05-e941-4721-9212-4749743d4329' in /home/vagrant/code/sites/troovy/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:27

Update 2. Confirmed, also fails in console:

SQLSTATE[HY000] [1049] Unknown database '8b3c0438-7dc3-4f4d-a652-93aea2e60ac2' (SQL: select * from information_schema.tables where table_schema = 8b3c0438-7dc3-4f4d-a652-93aea2e60ac2 and table_name = migrations and table_type = 'BASE TABLE')

@dambridge
Copy link
Sponsor Author

Ultimately, I think I tracked it down to a missing config setting. Didn't have the default connection set to 'tenant'.

@martincarvalho
Copy link

Hey @dambridge , how did you fix the command does not exist issue?

My artisan call is pretty much exactly like yours:
Artisan::call('tenants:artisan "migrate --seed" --tenant=' . $this->id);

But I'm still getting:
Symfony\Component\Console\Exception\CommandNotFoundException The command "tenants:artisan" does not exist.

This is how my createDatabase() method looks like:

    public function createDatabase()
    {
        DB::statement('CREATE DATABASE `'.$this->database.'`');
        Artisan::call('tenants:artisan "migrate --seed" --tenant=' . $this->id);
    }

@dambridge
Copy link
Sponsor Author

Hi @martincarvalho

Still working through this. This call works perfectly when I have it in a job (I have made all jobs tenant aware by default in the config).
Artisan::call('tenants:artisan "migrate --seed" --tenant=' . $this->tenant->id);

However... it fails when I run it in a controller directly with the same error! Very strange, still looking at it.

@dambridge
Copy link
Sponsor Author

If it works in my job, then something about environment/context must be at play is my thinking. Not sure if this is relevant, but found this in the MultiTenancy service provider:

if ($this->app->runningInConsole()) {
            $this
                ->registerPublishables()
                ->bootCommands();
        }
protected function bootCommands(): self
    {
        $this->commands([
            TenantsArtisanCommand::class,
        ]);

        return $this;
    }

Maybe this means the command is only available from within console? And because jobs run 'out of process' it works?

@dambridge dambridge reopened this May 29, 2020
@dambridge
Copy link
Sponsor Author

This is greasy, but it works in controller:
exec('cd ' . base_path() . ' && php artisan tenants:artisan "migrate --seed" --tenant=' . $tenant->id);

@freekmurze
Copy link
Member

In the vendor of your app, move that bootCommands outside of runningInConsole and see if just using Artisan::call. work for the command. If it does, I'd accept a PR that makes this change in the package 👍

@martincarvalho
Copy link

After moving the bootCommands outside of runningInConsole I got the Artisan ::call to work IF in a controller.
It does not work if called inside the Tenant model.
If possible I'd like to create the database AND run the migration inside the createDatabase() method on my Tenant model, as suggested in the documentation.
Is this possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants