0

Does this happened to someone else, too. I created a site and at some point my migrations just don't wanna run anymore. Laravel is retrieving error that the table does not exist then I ran php artisan migration:reset and manually dropped all tables from database, but same error was displayed again.

Error

Base table or view not found: 1146 Table 'db_blogtech.settings' doesn't exist

Here is that migration:

public function up()
{
    Schema::create('settings', function (Blueprint $table) {
        $table->id();
        $table->string('site_name')->default("Digy Studio");
        $table->text('site_description')->nullable();
        $table->string('site_facebook')->nullable();
        $table->string('site_instagram')->nullable();
        $table->string('site_twitter')->nullable();
        $table->string('site_linkedin')->nullable();
        $table->string('site_behance')->nullable();
        $table->string('site_dribbble')->nullable();
        $table->string('site_email')->nullable();
        $table->string('site_field_one')->nullable();
        $table->string('site_field_one_value')->nullable();
        $table->string('site_field_two')->nullable();
        $table->string('site_field_two_value')->nullable();
        $table->string('site_field_three')->nullable();
        $table->string('site_field_three_value')->nullable();
        $table->string('site_field_four')->nullable();
        $table->string('site_field_four_value')->nullable();
        $table->string('site_copyright')->nullable();
        $table->string('site_creator_name')->nullable();
        $table->string('site_creator_link')->nullable();
        $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::dropIfExists('settings');
}

EDIT Since the problem is that Setting model is used in AppServiceProvider here is that part of the code. I am sharing it here to all views so I need it in all views and I am trying to avoid repeating myself in code. If there is other solution please write in comment or if someone knows how to put this in try catch

Here is the part of the code:

public function boot()
    {
        View::share('settings', Setting::firstOrFaiL());
    }
Sead Silajdzic
  • 298
  • 1
  • 4
  • 21
  • Does this article help you? https://stackoverflow.com/questions/43186512/laravel-wont-let-me-migrate-a-table-because-it-already-exists – Thân LƯƠNG Đình Dec 07 '20 at 14:43
  • If you dropped everything then try `migrate:fresh` – apokryfos Dec 07 '20 at 15:09
  • @apokryfos tried does not help – Sead Silajdzic Dec 07 '20 at 15:16
  • @ThânLƯƠNG it does not help :3 mine problem is that it does NOT exist – Sead Silajdzic Dec 07 '20 at 15:16
  • 1
    Check the order in which your migrations are running. Make sure nothing uses the settings table before it's created. If something does use the table, might be worth moving that. Migrations run alphabetically so you can rename the migrations file to control what runs first – apokryfos Dec 07 '20 at 15:25
  • There must be more to the error message than this. In addition to showing you the SQL it's trying to run, you should be able to get a stack trace from laravel.log and see what code is causing the problem. – miken32 Dec 07 '20 at 15:29
  • @miken32 here is the full error message: https://prnt.sc/vxo0qg – Sead Silajdzic Dec 07 '20 at 17:18
  • @apokryfos I know about that issue but setting model or migration is something like standalone... I don't use it anywhere and its only use is to pull some data from db – Sead Silajdzic Dec 07 '20 at 17:19
  • 1
    From the error you shared you seem to be using the settings table in one of your providers. It's a kind of chicken and egg problem. You can't run the migrations without booting the app, but you can't boot the app if the settings table doesn't exist. If this is indeed the case I would wrap the getting of the settings in a `try... catch` and fall back to some defaults in case the table doesn't exist. – apokryfos Dec 07 '20 at 17:35
  • Does this answer your question? [Can't start Laravel, I get "Base table or view not found" error](https://stackoverflow.com/questions/42511841/cant-start-laravel-i-get-base-table-or-view-not-found-error) – miken32 Dec 07 '20 at 17:40
  • @apokryfos Yes I am using it in the service provider to share settings to all views `View::share('settings', Setting::firstOrFaiL());` How can I fix it? – Sead Silajdzic Dec 07 '20 at 18:55
  • @SeadSilajdzic Could you please share full content of the migration file (ex: name of class)? – Thân LƯƠNG Đình Dec 07 '20 at 19:46
  • I've answered the question but can you please update your question to contain all the additional information regarding your problem? – apokryfos Dec 07 '20 at 19:52
  • @apokryfos Question is edited, I have added that part from ServiceProvider – Sead Silajdzic Dec 08 '20 at 08:24

1 Answers1

1

It is discouraged to use the database in a service provider. This is because not all requests will need a database connection or (in your case) to render a view, meaning you're connecting to the database without needing to potentially.

For your particular use case I would recommend using a view composer e.g. add this in your provider:

View::composer('*', function ($view) {
    if (!View::shared('settings')) {
       View::share('settings', Setting::firstOrFaiL());
    }
});

This way your settings are not read until any view is actually composed.

If you do insist on having this in the provider directly then you can ensure it only runs in web requests:

public function boot()
{
    if (!app()->runningInConsole() && !app()->runningUnitTests()) {
        View::share('settings', Setting::firstOrFaiL());
    }
}

apokryfos
  • 38,771
  • 9
  • 70
  • 114
  • This is working fine but now as you said if this is not a good practice is there a better way? Is it better just to go manually repeat that part of code in all controllers where I need settings? I am fairly new to laravel and trying to learn some more advanced features :) – Sead Silajdzic Dec 08 '20 at 14:50
  • 1
    The ideal is to use a view composer but only include the view names that need the settings. Instead of `"*"` for the view name you just put an array e.g. `[ 'layouts.index', ...]` personally I have one main view and all my other views inherit from it and my view composer for that view is responsible for passing data that all views should have – apokryfos Dec 08 '20 at 16:29
  • Just wanted to ask you if it is possible if I have one main view from which all others extend to put just that one and will all others work :D You helped me a lot thank you! – Sead Silajdzic Dec 08 '20 at 17:00
  • I get this error now `Undefined variable: settings (View: C:\xampp\htdocs\...\resources\views\index.blade.php)`. I have put that part of the code you sent in the comment and $settings is used in `layouts. home` (from which all other views inherit including index) – Sead Silajdzic Dec 08 '20 at 17:14