I have table "table_1" which was formulated by many migrations (add/change fields)
I want to create new table which is copy of existing one "copy_of_table_1" (using migrations) with the same structure as "table_1" what is the best way to do this ?
I want to avoid make new migration and copy paste all added changed fields
You can do this with a raw query:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class MyNewTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
DB::statement('CREATE TABLE newtable LIKE oldtable; ');
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('newtable');
}
}
Definitely not recommended, but possible.
Best way is to create new migration and add fields from all add/change migrations. I don't see any smarter solution here.
Related
Is there a way how I can change the migrations order without remaking them all? Because now I have a problem with my foreign keys -_- (working with laravel)
Roll back all the migrations (or start with a fresh database);
Change the dates that form the first part of the migration filenames so they're in the order you want (eg. for 2014_06_24_134109_update_database.php, the date & time is 2014-06-24, 13:41:09);
Run the migrations again.
With respect to your comment about foreign keys... I'm not sure that the problem is with Laravel. More likely, it's just MySQL.
I avoid foreign keys because once you get a moderately complicated set of relations, you start to run into problems with database consistency like you're seeing - it's hard for the server to figure out what order to create the tables & relationships in, and it starts to cause difficulties with things like dump files (for backups).
You have to create a custom command that executes
php artisan migrate:refresh --path=/database/migrations/name_migration.php repeately with the migrations's name in the order you want.
Like this:
Create Command class with: php artisan make:command NameClass
Go to app/Console/Commands/ and find the class file NameClass.php
In the NameClass.php you have two attributes $signature (the name of the command) and $description (Information about what your command does).
Set the name and the description of your command.Ex: protected $signature='namecommand'; protected $descripton = 'This method migrate tables in order'
Inside the NameClass.php you have a method called handle(), here you have to declare the code you want to be executed when you write the command.
Register your command. Go to app/Console/Kernel.php and add your class to the list of Command Classes.
protected $commands = [
Commands\NameClass::class,
];
Write the command in the terminal. php artisan namecommand
Example:
php artisan make:command MigrateInOrder
app/Console/Commands/MigrateInOrder.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class MigrateInOrder extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'migrate_in_order';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Execute the migrations in the order specified in the file app/Console/Comands/MigrateInOrder.php \n Drop all the table in db before execute the command.';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
/** Specify the names of the migrations files in the order you want to
* loaded
* $migrations =[
* 'xxxx_xx_xx_000000_create_nameTable_table.php',
* ];
*/
$migrations = [
'2020_04_18_005024_create_users_types.php',
'2014_10_12_000000_create_users_table.php',
'2014_10_12_100000_create_password_resets_table.php',
'2019_08_19_000000_create_failed_jobs_table.php'
];
foreach($migrations as $migration)
{
$basePath = 'database/migrations/';
$migrationName = trim($migration);
$path = $basePath.$migrationName;
$this->call('migrate:refresh', [
'--path' => $path ,
]);
}
}
}
Go to app/Console/Kernel.php and register your command
protected $commands = [
Commands\MigrateInOrder::class,
];
Excute the command
php artisan migrate_in_order
Taking inspiration from PhpMyAdmin, I put all foreign keys definitions in a specific far future file, eg : 2999_12_31_235959_foreign_key.php
<?php
use App\Models\Post;
use App\Models\Tag;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ForeignKeys extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
// Post_tag
Schema::table(Post::NOM, function (Blueprint $table) {
$table->foreign('id_post')
->references('id_post')
->on(Post::NOM);
$table->foreign('id_tag')
->references('id_tag')
->on(Tag::NOM);
});
}
}
The only con I see is not having foreign keys definition in migration.
For the pros :
Keeping database relations
Do not care of table creation order
The best and easiest thing would be to just rename the migration yyyy_mm_dd_hhmmss_migration_name. If your migration follows this sequence, Laravel will ensure to run the migration is sorted form of date,
Building on the answer of Galeokerdo which suggests creating a separate migration file for the foreign keys, and putting the date in the far future, I tried it and it worked great. But then I started thinking of the rollback. It turned out that Laravel takes the reverse order when rolling back migrations. That is, the latest file is rolled back first.
Since the rollback will not work with the foreign key constraints in place, I tried putting my foreign-key-removal code in the "down" method of the separate foreign key migration, having found out that the file will execute first before all other migration files. Like thus:
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('tablename', function (Blueprint $table) {
$table->dropForeign('tablename_foreignkey_foreign');
});
}
"tablename_foreignkey_foreign" is the name of the foreign key constraint. By default, it is
"nameofthetable_foreignkeycolumn_foreign"
I just wanted to share this in case anybody is struggling with it the way I did.
You only need to change migrations order. if bands or stage tables are below users table, MySQL don't find the references. =)
I`m running a new installation of Laravel, with clean database and files.
I created a table named "frooth" and it has the columns id, title and created_at (id PK, varchar and datetime)
When I run "php artisan make:migration frooth" command, the created migration file is empty, only containing the up() and down() functions and nothing more (no columns)
How can I solve this, I followed the basic configuration of the framework as documented in official website, I can access and create functions in artisan as expected, only migrations its not working.
I generated the project with the command: composer create-project --prefer-dist laravel/laravel blog
create table laravel.frooth
(
id int auto_increment
primary key,
title varchar(250) null,
created_at datetime null
);
The PHP class generated in database/migrations/2019_10_25_012925_frooth.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Frooth extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
//
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
}
}
Console output:
php artisan make:migration frooth
Created Migration: 2019_10_25_012925_frooth
Delete that table you made manually and delete that migration file.
Run php artisan make:migration create_frooths_table
Then add your columns to the new migration file.
Something similar to this:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Frooth extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('frooths', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('frooths');
}
}
Then run php artisan migrate
For the id you might need to use $table->bigIncrements('id'); if using Laravel 6
I just started to work on a laravel project for my school assignment. I just have started it for about a week so my fundamental knowledge about laravel is not complete.
Today I bump into a problem with model many to many relationship in laravel. I create 2 model with migration A and B. In App\A.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class A extends Model
{
//
public function B(){
return $this->belongsToMany('App\B');
}
}
and in App\B.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class B extends Model
{
//
public function A(){
return $this->belongsToMany('App\A');
}
}
I think it should do the job. But when I use seeder to create dummy data, I got the error with is that table A_B is not created. I assume that I must create empty table A_B for 2 pivot columns which is annoying. Is there a better way, a proper way to create many to many relationship without manually create pivot table for them?
I'm afraid not. There are shortcuts to doing it, like the way they show here but you will end up doing some manual work to create the table. You will end up using a migration anyway, but depending on the amount of control you want with the pivot, you might want to use a model for that. Using a model for a pivot table is not mandatory.
https://laravel.com/docs/5.5/migrations#creating-tables
This could be what your migration would end up looking like:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateABTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('A_B', function (Blueprint $table) {
$table->increments('id');
$table->integer('a_id')->unsigned();
$table->integer('b_id')->unsigned();
$table->foreign('a_id')->references('id')->on('a')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('A_B');
}
}
But if you really wanted to, you could also create a custom table (with a custom name like ABRandomName) using a new model. Just look for the Defining Custom Intermediate Table Models header in the documentation:
https://laravel.com/docs/5.5/eloquent-relationships#many-to-many
I would like to rename a table in the database from topics to galleries and I have created a migration that will rename my table.
Schema::rename('foo', 'bar');
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RenameTopicsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
//
Schema::rename('topics', 'galleries');
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
Schema::rename('galleries', 'topics');
}
}
However will the Topic Model and Topic Controller be automatically renamed? Or will I have to refactor my code? Does Laravel provide a way to do this easily?
In short my question is - How do you change your schema easily in laravel? (models/controllers/database/requests/transformers ect..)
To answer this question. Laravel does not provide a out-of-the-box way to rename your tables at the same time as your Models/Controllers.
You must manually refactor your code after you change your database schema.
An example of this is lets say i have a posts table and i want to rename it to blogs. Well my posts model and posts controller wont be helpful after i update the schema so i will need to change those over as well. Routes will need to be updated. If I am using views those will need to be updated. In my case i was using transformers and requests so those need to be manually updated.
If you can, try to avoid changing your schema :D
I am trying to learn laravel, and am following a bunch of tutorials
I am trying to save a object I created inside my model to my database table-contact,but when I do the modelObject->save command in tinker it replaces my table name by contacts instead of contact
Now I know about the snake case plural name system in laravel so I explicitly rename my table in the model as follows :
protected $table='contact';
But still I get the same error as
`'base table or view not found **laravel.contacts**'`
Here is my migration :
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateContactTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('contact', function (Blueprint $table) {
$table->increments('id');
$table->text('address');
$table->string('email');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('contact');
}
}
My model which I create like this:
php artisan make:model contact
The model that was created:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class contact extends Model
{
protected $table='contact';
}
note :that protected $table='contact' was manually added by me later
Now I create object in tinker as :
$contact=new App\contact
$contact->address='myaddress'
$contact->email='myemail'
And then try to save the object to the database using
$contact->save
But like I've said before laravel tries to save it to contacts instead of contact table
Also,The object '$contact' doesn't reference the default values of timestamp and id in the model as it does in the tutorial may be someone can hint me why..
I figured what I was I doing wrong ,apparently I have to restart tinker every time I change something in the model class I create. Writing the based object again referencing the App/modelClass doesn't seem to work