Wrong migration called - laravel

I have 2 migrations, the first one has the following name 2019_11_06_171637_create_settings_table.php and structure:
class CreateSettingsTable extends Migration
{
public function up()
{
Schema::create('settings', function (Blueprint $table) {
//code
});
}
//function down
}
the second one has the following name 2020_07_08_246856_create_settings_table.php and structure:
class CreateAnotherSettingsTable extends Migration
{
public function up()
{
Schema::create('another_settings', function (Blueprint $table) {
//code
});
}
//function down
}
When I run php artisan migrate all migrations going well until Migrating: 2020_07_08_246856_create_settings_table - it's trying to run the previos migration(2019_11_06_171637_create_settings_table.php) and fire an exception Table 'settings' already exists.
Does this mean that the name of the migration file must be unique after the date and numbers?

I've read somewhere that Laravel uses the filenames of migrations to call the correct class for the migration. I've tried to look up some documentation or reference on this, but I can't find it anymore. You currently have the same filename twice (if you ignore the timestamp part) which results in Laravel calling the same class twice.
If you rename the second file (the one with the CreateAnotherSettingsTable class) to 2020_07_08_246856_create_another_settings_table.php, your problem will be fixed.

I found this very interesting so I looked within the source code.
\Illuminate\Database\Console\Migrations\TableGuesser will use the migration name to determine whether if the table already exists.
// Next, we will attempt to guess the table name if this the migration has
// "create" in the name. This will allow us to provide a convenient way
// of creating migrations that create new tables for the application.
if (! $table) {
[$table, $create] = TableGuesser::guess($name);
}
This is executed upon artisan:make and migrate:install commands.
So ultimately, as your migration file name is create_settings_table.php, the "settings" word is what will be used for checking.
The code that laravel uses for this determination is:
const CREATE_PATTERNS = [
'/^create_(\w+)_table$/',
'/^create_(\w+)$/',
];
const CHANGE_PATTERNS = [
'/_(to|from|in)_(\w+)_table$/',
'/_(to|from|in)_(\w+)$/',
];
/**
* Attempt to guess the table name and "creation" status of the given migration.
*
* #param string $migration
* #return array
*/
public static function guess($migration)
{
foreach (self::CREATE_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[1], $create = true];
}
}
foreach (self::CHANGE_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[2], $create = false];
}
}
}
So your solution is to rename one of those migration files.
CreateAnotherSettingsTable will be the best, standard following, name

Related

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

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

How to populate database with pre-set data? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I am trying to run finished web app but it gives me error which is almost certainly due to app trying to find out which language version to use. I've done succesful migration but all tables (country, language etc. ) are empty. How do I populate them with data the app is looking for?
You can create default items as part of your migrations.
public function up()
{
Schema::create('users', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
});
$user = new App\User;
$user->name = 'Bob';
$user->save();
}
You can also build seeders.
There is a default DatabaseSeeder class included in a freshly installed Laravel app. It allows you to insert data to the database. Look for it in the database/seeds directory:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
}
}
If you want to add data to the countries table, write it like this:
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('countries)->insert([
'code' => 'fra',
'name' => 'France',
]);
}
}
Then use the db:seed command to seed your database:
php artisan db:seed
That's it.
You can also create your own Seeders, for example a ProductionDatabaseSeeder or a DummyDataSeeder, auto run your seeders when you migrate a database or even use model factories to easily generate dummy data. See more in the laravel docs.
I decided to go with the approach of using the migration, so that the database will be filled with the data I need straight immediately after the rows themselves are created. However, instead of adding each record individually as in ceejayoz's answer, I found it more efficient to use mass assignment functions:
class CreateManufacturersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->string("slug")->unique();
$table->string("name");
$table->timestamps();
});
Manufacturer::firstOrCreate(
["slug" => "bob", "name" => "Bob"]
);
Manufacturer::firstOrCreate(
["slug" => "alice", "name" => "Alice"]
);
Manufacturer::firstOrCreate(
["slug" => "hashim", "name" => "Hashim"]
);
}
The firstOrCreate() method saves you from needing to create a new instance of the model as well as persisting every record that you just created.

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.

Laravel session table add additional column

I want to add an extra column user_id on session table.
The reason is, some time there are spammer to sign up fake account, once I know that the user is spammer, I want to log the user out by deleting the session record.
Is it possible to achieve this?
This is the session migration schema:
Schema::create('sessions', function($table)
{
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
$table->integer('user_id')->unsigned(); //// ADD IT!
});
You can add whatever column you like on it, Laravel won't mind.
Or you can create a new migration and make it add a column on that table.
$table->integer('user_id')->unsigned();
You can create a Model for it:
class SessionModel extends Eloquent {
}
And do whatever you need with it:
$session = SessionModel::find(Session::getId());
$session->user_id = 1;
$session->save();
But if you're thinking about adding more info to the payload, which is where Laravel keeps the session data, although I think it's possible, you'll have to dig a bit more in Laravel's code to do that.
Short version of migration
if( Schema::hasTable('sessions') ) {
$table->integer('user_id')->unsigned();
}
Need to check if exist session table. Or create it before:
php artisan session:table
php artisan migrate
https://laravel.com/docs/5.7/session#introduction
This is the session migration schema:
Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->unique();
$table->integer('user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('device')->nullable();
$table->text('payload');
$table->integer('last_activity');
});
To add the information to the payload after adding COLUMN to the TABLE, just change the DatabaseSessionHandler class.
path: vendor/laravel/framework/src/illuminate/Session
Ex:
1º Creates the function
protected function device()
{
$agent = new \Jenssegers\Agent\Agent;
if ($agent->isDesktop()){
$device = 'desktop';
}
return $device;
}
2º add in function addRequestInformation (& $ payload)
protected function addRequestInformation(&$payload)
{
if ($this->container->bound('request')) {
$payload = array_merge($payload, [
'ip_address' => $this->ipAddress(),
'user_agent' => $this->userAgent(),
'device' => $this->device(),
]);
}
return $this;
}
Ready, device added to the table when the user login.

Resources