SpencerKMedia
SpencerKMedia

Reputation: 43

Laravel: php artisan migrate:fresh failed ``database.themes`` does not exist

I am trying to run php artisan migrate:fresh to publish a modification to my seeder. It partially worked, it removed all of the tables in the database but it won't recreate them because Table 'database.themes' does not exist. I have included my Themes.php model, my ThemesController.php and any other resources requiring Themes below to hopefully make sense of this.

2020_11_14_125914_create_themes_table (Migration)

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateThemesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('themes', function (Blueprint $table) {
            $table->id('theme_id');

            $table->string('theme_title')->default('Main');
            $table->string('theme_slug')->default('main')->unique();
            $table->text('theme_description')->nullable();
            $table->string('theme_uri')->default('laravel.cmsbase.com')->nullable();
            $table->string('theme_version')->default('1.0.0')->nullable();
            $table->string('theme_license')->default('The MIT License (MIT)')->nullable();
            $table->string('theme_tags')->nullable();
            $table->string('theme_type')->default('web');
            $table->string('author_name')->default('Spencer K Media');
            $table->string('author_uri')->nullable();

            $table->boolean('is_theme')->default(1)->nullable();
            $table->timestamps();
        });

        DB::table('themes')->insert([
            'theme_id' => '1',
            'theme_title' => 'Core theme',
            'theme_slug' => 'main',
            'theme_description' => 'Default theme for the theme package',
            'theme_uri' => 'https://laravel.cmsbase.com',
            'theme_version' => '1.0.0',
            'theme_license' => 'The MIT License (MIT)',
            'theme_tags' => 'default, simple, base',
            'theme_type' => 'web',
            'author_name' => 'Spencer K Media',
            'author_uri' => 'https://spencerkmedia.com',
            'is_theme' => 1,
        ]);
    }

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

Themes.php (Model)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Themes extends Model
{
    use HasFactory;
    
    protected $fillable = ['theme_title', 'theme_slug', 'theme_uri', 'theme_version', 'theme_license', 'theme_tags', 'theme_type', 'author_name', 'author_uri', 'is_theme'];
}

ThemesController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Themes;

use Carbon\Carbon;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;

class ThemeSettingsController extends Controller
{
    public $themes;
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $themes = Themes::get();
        return view('admin.settings.theme', compact('themes'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function activate()
    {
        
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request, $theme, $json)
    {
        // Get the path of theme.json
        $path = glob("/resources/views/themes/{,*/}theme.json", GLOB_BRACE);

        // Parse the json file into array with $json
        $json = json_decode(file_get_contents($path), true);

        var_dump($json);

        $this->validate($request, [
            'is_theme' => 'accepted'
        ]);

        $theme = new Themes();

        $theme->theme_title = $json->theme_title;
        $theme->theme_slug = strtolower($json->theme_title);
        $theme->theme_description = $json->theme_description;
        $theme->theme_uri = $json->theme_uri;
        $theme->theme_version = $json->theme_version;
        $theme->theme_license = $json->theme_license;
        $theme->theme_tags = $json->theme_tags;
        $theme->theme_type = $json->theme_type;
        $theme->author_name = $json->author_name;
        $theme->author_uri = $json->author_uri;
        $theme->is_theme = $request->is_theme;
        $theme->save();
        notify()->success('Theme successfully enabled :)', 'Success');
        return redirect()->back();
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

RouteServiceProvider

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use App\Models\Themes;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * The path to the "home" route for your application.
     *
     * This is used by Laravel authentication to redirect users after login.
     *
     * @var string
     */
    public const HOME = '/home';

    /**
     * The controller namespace for the application.
     *
     * When present, controller route declarations will automatically be prefixed with this namespace.
     *
     * @var string|null
     */
    // protected $namespace = 'App\\Http\\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $settings = Themes::get();
        $this->configureRateLimiting();

        $this->routes(function () use ($settings) {
            Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace)
                ->group(base_path('routes\api.php'));

            Route::middleware('web')
            ->namespace($this->namespace)
                ->group(base_path('routes\web.php'));


            foreach ($settings as $key => $setting) {
                Route::middleware('web')
                ->group(base_path('resources/views/themes/' . $setting->theme_slug . '/route.php'));
            }
        });
    }

    /**
     * Configure the rate limiters for the application.
     *
     * @return void
     */
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60);
        });
    }
}

Web.php (Route File)

Route::prefix('settings')->name('settings.')->group(function () {
    Route::get('/home', function () {
        return view('admin.settings.index');
    })->name('index');
    Route::get('/general', function () {
        return view('admin.settings.general');
    })->name('general');
    Route::get('/site', function () {
        return view('admin.settings.site');
    })->name('site');
    Route::get('/theme', function () {
        return view('admin.settings.theme');
    })->name('theme');
});

Any help is appreciated and thank you in advance!

Upvotes: 0

Views: 707

Answers (1)

Mathias Hillmann
Mathias Hillmann

Reputation: 1837

Laravel runs Providers before the command on artisan commands, so its trying to $settings = Themes::get(); on RouteServiceProvider and failing, thus the error. For a temporary fix remove that code and then run the migrate command.

For a more permanent fix, you can check if the model/table exists before running the query:

    public function boot()
    {
        if($settings = Themes::get()){
            $this->configureRateLimiting();

            $this->routes(function () use ($settings) {
                Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                    ->group(base_path('routes\api.php'));

                Route::middleware('web')
                ->namespace($this->namespace)
                    ->group(base_path('routes\web.php'));


                foreach ($settings as $key => $setting) {
                    Route::middleware('web')
                    ->group(base_path('resources/views/themes/' . $setting->theme_slug . '/route.php'));
                }
            });
        }
    }

Upvotes: 1

Related Questions