Search code examples
phplaraveleloquentmigrationlaravel-artisan

Laravel: renaming database table breaks functionality


I'm still quite new to Laravel, Eloquent and Artisan. What I'm trying to do is pretty easy: I want to create a new Eloquent model AboutUs, along with a migration file to create the table about_us.

I run the following command:

PHP artisan make:model AboutUs -m

This generates the model and migration file, however, the migration file is named '2017_07_18_211959_create_about_uses_table.php', automatically adding the unnecessary 'es' to 'us', and creating a table 'aboutuses' instead of 'about_us'. If I manually change the migration file like so:

<?php

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

class CreateAboutUsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('about_us', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->boolean('active');
            $table->string('title')->nullable();
            $table->text('text')->nullable();
        });
    }

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

The model like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class AboutUs extends Model
{
    protected $fillable = ['id', 'active', 'title', 'text'];

    public static function getAboutUs()
    {
        return AboutUs::find(1);
    }

    public function postAboutUs($session, $active, $title, $text)
    {
        $aboutUs = $session->get('about_us');
        array_push($aboutUs, ['active' => $active, 'title' => $title, 'text' => $text,]);
        $session->put('about_us', $aboutUs);
    }
}

Then run the migration:

PHP artisan migrate

The database table 'about_us' is created correctly, but when I insert a row in the table and attempt to use getAboutUs, it crashes, the laravel.log stating that:

local.ERROR: exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ID226233_db.aboutuses' doesn't exist' in C:\PHP Projects\xxx\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:77

I can see that there are still references to "aboutuses" in the autoload_classmap and autoload_static files. Changing this manually doesn't fix the issue, nor does running:

composer dump autoload

Next, I tried to simply not rename the table, but run the migration to create the initial "aboutuses" table. This fixed the functionality, as the model now works correctly. However, if I now add a new migration with:

Schema::rename('aboutuses', 'about_us');

This renames the table in the DB, but not in the autoload files or wherever else, resulting in broken functionality.

Surely there must be an easier way to either:

  • create a model with migration file with a FIXED name, instead of it automatically changing the name by adding an unnecessary suffix.
  • rename a model and change the necessary files to prevent the model from breaking.

Could anyone point me in the right direction before I lose my mind over this? :)


Solution

  • You can specify a custom table name in your Eloquent model class. Here is the example from the docs:

    <?php namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Flight extends Model
    {
        /**
         * The table associated with the model.
         *
         * @var string
         */
        protected $table = 'my_flights';
    }
    

    Source: https://laravel.com/docs/5.4/eloquent#eloquent-model-conventions

    Hope that helps.