Nublust's avatar

Service provider and db query

Is it possible to use eloquent and query my database in a service providers boot method?

I'm trying to use envoyer, but when it installs the composer dependencies and runs php artisan clear-compiled, the deployment breaks:

[Illuminate\Database\QueryException]                                                                                        
  SQLSTATE[42S02]: Base table or view not found: 1146 Table 'forge.countries' doesn't exist (SQL: select * from `countries`)  

Am I doing something obviously wrong?

0 likes
11 replies
cimrie's avatar

That isn't suggesting any issue with Eloquent imo. It looks like you haven't migrated the DB in forge/envoyer. I haven't used either service so I'm not sure if it is meant to do that for you automatically. Go on to the server command line in your project and use

php artisan migrate

If you want to seed your database (if you have defined seeders)

php artisan migrate --seed

Hope that helps

Nublust's avatar

The problem is in order to run the migration, you need to have an installation of laravel already existing including its dependencies, if my understanding is correct? So I can't run the migration until it is all installed successfully, which it can't do because I haven't run the migration and then the cycle continues haha.

cimrie's avatar

This would suggest it is a bad idea to have the code that touches your DB in a service provider, as they are the first things to boot up in Laravel and the whole application might not have loaded by the time you are making queries.

I would suggest either refactoring and moving the logic to somewhere that is executed after all service providers, or alternatively disable the service provider, run the migration and then re-enable it. That might work, but obviously you would have to remember the process each time you set up the app.

Nublust's avatar

I'm using a view composer and @JeffreyWay did the same thing in one of his screencasts so I assume it would be safe to do?

I probably will refactor and place it somewhere else at this rate, its just annoying/confusing that it seems to work where I have seen it elsewhere but not for me.

juliomoreira's avatar

Sorry to bump this old thread but I ran across this problem today trying to "fresh run" an old project of mine.

I figured out that if you try to hit the database outside $view->composer(); method it will throw the exception, of course.

In my case it was:

$departments = $department->lists('name', 'id');
$view->composer('ticket.partials.modals.create', function ($view) use ($departments) {
    $view->with('departments', $departments);
});

The refactoring that worked for me was just moved the line that was fetching the model inside the $view->composer(); method closure like so:

$view->composer('ticket.partials.modals.create', function ($view) use ($department) {
    $departments = $department->lists('name', 'id');
    $view->with('departments', $departments);
});

Hope this helps.

Cheers,

2 likes
jamin87's avatar

I ran into the same issue with database queries in a service providers' boot method.

After scratching my head for a while I found a simple fix.

Just wrap everything in an if statement which checks for the existence of the tables you're querying.

public function boot()
{
    if (\Schema::hasTable('your_table')) {
            // Your super fun database stuff
    }
}
3 likes
pmall's avatar

Why do you all want to run queries in a service provider?

jamin87's avatar

I'm using it to grab a value for the view shared() method.

shamaseen's avatar

The best I can think of is to use try-catch to prevent failing on new project. you will need to catch the EXACT exception to prevent all exceptions from being catched.

try { //// ur code } catch (\Illuminate\Database\QueryException $exception) { report($exception); }

Please or to participate in this conversation.