Laravel: renaming database table breaks functionality - laravel

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? :)

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.

Related

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax error when seeding data to db

I am getting this error when I try to seed data into the database. I have the bookings table and a bookings package table, seeder, factory and models, and also a pivot table that links them.
here is my bookingpackage seeder
<?php
namespace Database\Seeders;
use App\Models\bookingpackage;
use Illuminate\Database\Seeder;
class BookingpackageSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
bookingpackage::create(['package_name'=>'Dj and Full Sound System',
'package_description'=>'Dj and Full Sound System.Dj and Full Sound System',
'package_price'=>'sh 80,000']);
}
}
here's bookingseeder
$fullpackage=bookingpackage::where('package_name','Dj and Full Sound System',
'package_description','Dj and Full Sound System.Dj and Full Sound System',
'package_price','sh 80,000')->first();
$fullsetpackage=Bookings::create([
'full_name'=>'Best Promoters',
'location'=>'Nairobi',
'phone'=>'0792492584',
'is_booking'=>2,
'package_id'=>1,
'email'=>'Werupromoter#admin.com',
'date'=>'07/02/2021',
'event_id'=>'5',
'event_details'=>'we would like to book you for a wedding'
]);
$fullpackage->bookingpack()->attach($fullsetpackage);
my bookingpackages table looks like this
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBookingpackagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('bookingpackages', function (Blueprint $table) {
$table->id();
$table->string('package_name');
$table->text('package_description');
$table->string('package_price');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('bookingpackages');
}
}
where might have I gone wrong in my code.
The title is very vague but i think error is in this line
$fullpackage->bookingpack()->attach($fullsetpackage);
first check bookingpack() method is exist in Bookings model
and then modify this line with:
$fullpackage->bookingpack()->attach($fullsetpackage->id);
after that replace first query in bookingseeder with:
$fullpackage=bookingpackage::where("package_name", 'Dj and Full Sound System')
->where("package_description", "Dj and Full Sound System.Dj and Full Sound System")
->where("package_price", "sh 80,000")
->first();
or you can write "where" query another way like:
$fullpackage=bookingpackage::where([
['package_name', "=", 'Dj and Full Sound System'],
['package_description', "=", 'Dj and Full Sound System.Dj and Full Sound System'],
['package_price', "=", 'sh 80,000'],
])->first();

I got an odd question on laravel's migration [duplicate]

This question already has answers here:
Laravel seed issue, laravel is looking for plural table name
(2 answers)
Closed 1 year ago.
I have been trying to google this but I still couldn't pinpoint the exact answer to the question in my head.
I have used php artisan to create a migration file to set up a table called blogs (note the plural). Previously, the table was called blog (singular) and the factory would not seed because the error shown on the terminal was that no relations found for "blogs" - which didn't make sense to me because every reference I used in the controllers, models and factories were singular. It would not let me seed until I have rolled back the migration and re-created the table as blogs in plural form.
And the strangest thing is that I have kept everything else in singular still, anyone got any clues as to why the seeding works only when I used plural for the table's name?
This is my migration file after the table is revised from blog to blogs:
class CreateBlogsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('blogs', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('title', 255);
$table->text('body');
$table->text('user_id');
});
}
This is my factory - named BlogFactory:
namespace Database\Factories;
use App\Models\Blog;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class BlogFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Blog::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'title' => $this->faker->sentence, //Generates a fake sentence
'body' => $this->faker->paragraph(30), //generates fake 30 paragraphs
'user_id' => User::factory() //Generates a User from factory and extracts id
];
}
}
This is my model - named Blog:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
use HasFactory;
protected $fillable = [
'title',
'body',
'user_id',
];
}
This is my controller - named BlogController:
<?php
namespace App\Http\Controllers;
use App\Models\Blog;
use Illuminate\Http\Request;
class BlogController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return Blog::all();
}
I seem to recall similar issues regarding renamed class-names and/or tables... Could you try running "composer dump-autoload" after having all the migrations and/or class-name refactorings ready? I remember old class-names being somehow cached, which gave me an headache. Apparently dumping autoload should rebuild this cache.
Edit: With your newest edit you will not need to do this change as you have changed the migration from creating a blog table to creating a blogs table.
You will need to edit your model to understand that you use non-standard Laravel formatting for your table name.
Laravel, per default, will assume your table is a pluralized version of your model name. To override this, you need to add the following attribute to the model: protected $table = 'blog';
See below code; however, I suggest not changing this and sticking to the Laravel defined standards. The closer you are to doing it the way the framework wants, the easier it will be for you. Especially when learning, it is much easier not to fight the framework at the same time.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
use HasFactory;
protected $table = 'blog';
protected $fillable = [
'title',
'body',
'user_id',
];
}

How to index table column of specific database with code in laravel

I want to write code to index the column of a specific database table column.
Iam trying in this way
DB::connection('mysql2')->raw("ALTER TABLE `consignments` DROP INDEX customer_reference");
What is correct method for this process
You need to use the Laravel migrations, see this documentation:
Laravel Migrations
Laravel Migrations/Index related
You can execute this command in the shell on the project path and edit the created file in the database/migration path and add the index for the column following the documentation
php artisan make:migration add_index_to_consignments_table
Or create manually a file in the database/migrations path with a name like this:
2021_07_29_022532_add_index_to_consignments_table.php and copy/paste this php content
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddIndexToConsignmentsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up(): void
{
Schema::table('consignments', function (Blueprint $table) {
//Uncomment one line depending on what you need
//$table->index('customer_reference'); //If you need to add an index
//$table->dropIndex('name_of_index_on_table'); //If you need to remove an index
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down(): void
{
Schema::table('consignments', function (Blueprint $table) {
//Uncomment one line depending on what you need
//$table->dropIndex('name_of_index_on_table'); //If you need to add an index
//$table->index('customer_reference'); //If you need to remove an index
});
}
}
After creating the file with any method you have to execute this command in the shell on the project path:
php artisan migrate

Use trait in Laravel database migration

My superior told me I could create a seeder-like trait which I can then use inside a migration. When the migration is being run on the server the database automatically gets seeded while migrating instead of running a separate seeder after the migration succeeded.
Now I created a trait which I included in the database migration.
<?php
namespace App\Services;
use App\Models\Module\Module;
use App\Models\Plan\Plan;
/**
* PlanAndModuleGenerator class.
*/
trait PlanAndModuleGenerator
{
private static $plans = [
'free',
'basic',
'premium',
];
public function up()
{
foreach ($this->plans as $planName) {
// Get or create Plan.
$plan = Plan::create([
'machine_name' => '',
'name' => $planName
]);
}
}
}
My superior told me they did this before, but I can't find anything like this on the internet. I included my trait like this.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Services\PlanAndModuleGenerator;
class ModulePlan extends Migration
{
use PlanAndModuleGenerator;
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('module_plan', function (Blueprint $table) {
$table->unsignedInteger('plan_id');
$table->unsignedInteger('module_id');
$table->foreign('plan_id')->references('id')->on('plans');
$table->foreign('module_id')->references('id')->on('modules');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('module_plan');
}
}
When I run the migration the up function inside my trait isn't executed. I know this because the Plan table isn't seeded yet. Any ideas on how I might tackle this? As my superior isn't in the office the upcoming days and I can't access the repository where they did this before.
Besides this, can anyone tell me how I can properly debug this trait? The way I am doing this now, just running the migration and wait for errors, seems a bit cumbersome.
I don't see any reason for this trait at all, but if you really want to use it you would need to alias the up method of the trait and then call that in your up method of the migration:
class ModulePlan extends Migration
{
use PlanAndModuleGenerator { up as traitUp; }
public function up()
{
...
$this->traitUp();
}
}
It would be better to just use a different name for the method in the Trait, but there is no reason for this trait in the first place it would seem.
It will definitly not work because you have two up methods, one in your trait and the one in your migration. You need to delete the up in your migration and use the one in your trait as shown below. Here is the trait
<?php
namespace App\Services;
use App\Models\Plan\Plan;
use App\Models\Module\Module;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
/**
* PlanAndModuleGenerator class.
*/
trait PlanAndModuleGenerator
{
private static $plans = [
'free',
'basic',
'premium',
];
public function up()
{
$createmigration = Schema::create('module_plan', function (Blueprint $table) {
$table->unsignedInteger('plan_id');
$table->unsignedInteger('module_id');
$table->foreign('plan_id')->references('id')->on('plans');
$table->foreign('module_id')->references('id')->on('modules');
});
if ($createmigration) {
foreach ($this->plans as $planName) {
// Get or create Plan.
$plan = Plan::create([
'machine_name' => '',
'name' => $planName
]);
}
}
}
}
Confirm first that the migration was created before creating your Plan.
Here is how your migration should look like
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Services\PlanAndModuleGenerator;
class ModulePlan extends Migration
{
use PlanAndModuleGenerator;
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('module_plan');
}
}
Hope this will help

How to fix error Base table or view not found: 1146 Table laravel relationship table?

I am a new of laravel I try to create relationship many to many between table,My problem when I am insert data in to database I got errors
QueryException in Connection.php line 713: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'learn.category_posts' doesn't exist (SQL: insert into category_posts (category_id, posts_id) values (4, ))
can anyone help me pls . and here below is my migrate and code:
2016_08_04_131009_create_table_posts.php
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->text('title');
$table->text('body');
$table->timestamps();
});
}
2016_08_04_131053_create_table_categories.php
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
2016_08_04_131413_create_table_category_posts.php
public function up()
{
Schema::create('category_post', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories')->onUpdate('cascade')->onDelete('cascade');
$table->foreign('post_id')->references('id')->on('posts')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
}
and my model Posts.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Posts extends Model
{
protected $table = 'posts';
public function categories()
{
return $this->belongsToMany('App\Category');
}
}
Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $table = 'categories';
public function posts()
{
return $this->belongsToMany('App\Posts');
}
}
My PostsController.php
public function create()
{
$categories = Category::all();
return view('create',compact('categories'));
}
public function store(Request $request)
{
$post = new Posts;
$post->title = $request->title;
$post->body = $request->body;
$post->categories()->attach($request->categories_id);
return redirect()->route('posts.index');
}
My View create.blade.php
{!!Form::open(array('route' => 'store', 'method' => 'POST'))!!}
{{Form::text('title')}}<br>
{{Form::textarea('body')}}<br>
<select name="categories_id" multiple>
#foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</select>
<br>
{{Form::submit('submit')}}
{!!Form::close()!!}
It seems Laravel is trying to use category_posts table (because of many-to-many relationship). But you don't have this table, because you've created category_post table. Change name of the table to category_posts.
Laravel tries to guess the name of the table, you have to specify it directly so that it does not give you that error..
Try this:
class NameModel extends Model {
public $table = 'name_exact_of_the_table';
I hope that helps!
Schema::table is to modify an existing table, use Schema::create to create new.
The main problem for causing your table unable to migrate, is that you have running query on your "AppServiceProvider.php" try to check your serviceprovider and disable code for the meantime, and run php artisan migrate
You can add this in Post Model,
public function categories()
{
return $this->belongsToMany('App\Category','category_post','post_id','category_id');
}
category_post indicate the table you want to use.
post_id indicate the column where you want to store the posts id.
category_id indicate the column where you want to store the categories id.
For solving your Base Table or view not found error you can do As #Alexey Mezenin said that change table name category_post to category_posts,
but if you don't want to change the name like in my case i am using inventory table so i don't want to suffix it by s so i will provide table name in model as protected $table = 'Table_name_as_you_want' and then there is no need to change table name:
Change your Model of the module in which you are getting error for example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Inventory extends Model
{
protected $table = 'inventory';
protected $fillable = [
'supply', 'order',
];
}
you have to provide table name in model then it will not give error.
The simplest thing to do is, change the default table name assigned for the model. Simply put following code,
protected $table = 'category_posts'; instead of protected $table = 'posts'; then it'll do the trick.
However, if you refer Laravel documentation you'll find the answer. Here what it says,
By convention, the "snake case", plural name of the class(model) will be used as the table name unless another name is explicitly specified
Better to you use artisan command to make model and the migration file at the same time, use the following command,
php artisan make:model Test --migration
This will create a model class and a migration class in your Laravel project. Let's say it created following files,
Test.php
2018_06_22_142912_create_tests_table.php
If you look at the code in those two files you'll see,
2018_06_22_142912_create_tests_table.php files' up function,
public function up()
{
Schema::create('tests', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
Here it automatically generated code with the table name of 'tests' which is the plural name of that class which is in Test.php file.
You should change/add in your PostController: (and change PostsController to PostController)
public function create()
{
$categories = Category::all();
return view('create',compact('categories'));
}
public function store(Request $request)
{
$post = new Posts;
$post->title = $request->get('title'); // CHANGE THIS
$post->body = $request->get('body'); // CHANGE THIS
$post->save(); // ADD THIS
$post->categories()->attach($request->get('categories_id')); // CHANGE THIS
return redirect()->route('posts.index'); // PS ON THIS ONE
}
PS: using route() means you have named your route as such
Route::get('example', 'ExampleController#getExample')->name('getExample');
UPDATE
The comments above are also right, change your 'Posts' Model to 'Post'
try checking in the app if you are using the tables before it's created
such as appServiceProvider.php
you might be calling the table without being created it, if you are, comment it then run php artisan migrate.
This problem occur due to wrong spell or undefined database name. Make sure your database name, table name and all column name is same as from phpmyadmin
If you're facing this error but your issue is different and you're tired of searching for a long time then this might help you.
If you have changed your database and updated .env file and still facing same issue then you should check C:\xampp\htdocs{your-project-name}\bootstrap\cache\config.php file and replace or remove the old database name and other changed items.
Just run the command:
php artisan migrate:refresh --seed
If you are getting the error "SQLSTATE[42S02]: Base table or view not found" and you have no problem in your code, check if you have wrote the first letter of the table in capital letter.
Inspections >> inspections
capital case and small case letters matters on AWS environments.

Resources