Laravel Migration System for database tables - php

Due to Laravel migration system, we can create database tables by running the following command lines.
php artisan migrate:make create_users_table
class CreateUserTable extends Migration {
public function up() {
Schema::create('users', function($table)
{
$table->increments('id');
$table->string('email')->unique();
$table->string('name');
$table->timestamps();
});
}
public function down() {
Schema::drop('users');
}
}
php artisan migrate
If I work with relational database and have two tables, A and B. Table A is related to table B by a foreign key. Is it possible to create such database tables with Laravel Migration System? Or do I need to configure the relationship in phpmyadmin manually?

yes its possible to create forgien keys in laravel migration
$table->foreign('fk_id')->references('primary_key')->on('fk_table')->onDelete('cascade');

You can set foreign keys etc using the schema see here.
Example...
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
Also if you are creating tables I would advise using this site to help build your schema, much easier to visualise and work with.

Related

Laravel: Add column to table with updated migration

I'm trying to migrate a specific line in one migration file.
Example:
Before:
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('category_name');
$table->integer('parent_id')->nullable();
$table->timestamps();
});
After:
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('category_name');
$table->string('img_url'); // ← new column
$table->integer('parent_id')->nullable();
$table->timestamps();
});
And now I just want to migrate the line: $table->string('img_url');
Is it possible?
It sounds like you are trying to add a column to a table that has already been created via migration. If that is the case, rather than using Schema::create(...), you need to use Schema::table(...).
Typically, you would create a new migration for this:
$ php artisan make:migration add_img_url_to_categories
Which will create a new file at /database/migrations called something like 2019_10_21_165554_add_img_url_to_categories.php. Then add this code to the up() function:
public function up()
{
Schema::table('categories', function (Blueprint $table) {
$table->string('img_url');
});
}
Another option you have is to edit the migration exactly as you have done (per the code in your question), and then run:
$ php artisan migrate:fresh // drop all tables and re-run all migrations
or
$ php artisan migrate:refresh // reset and re-run all migrations
But keep in mind that these are both destructive operations – meaning you will lose any data you already have in your database. In early development, that might not matter. But you should really establish the habit of creating new migrations for database changes, rather than editing existing migrations.
The purpose of migrations is so that you (or anyone using your app) can quickly deploy a database that matches the schema your app is expecting.
During development, it is not uncommon to edit your migrations as you tweak your database schema to accommodate the features you are developing.
However, once you have deployed or published your app, you should consider all of the migrations to be locked or read-only. Any database changes from that point should be done in a new migration.

Foreign key constraint is incorrectly formed - Laravel

I'm on Laravel 5.8 on a XAMPP stack.
Consider these two migrations to create two tables:
post_categories table.
Schema::create('post_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('slug');
$table->string('status');
$table->timestamps();
});
posts table.
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('slug');
$table->mediumText('description');
$table->integer('views');
$table->integer('post_category_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
$table->foreign('post_category_id')->references('id')->on('post_categories');
});
When I run php artisan migrate, I'm getting the following error:
General error: 1005 Can't create table testdb.#sql-38d8_102 (errno: 150 "Foreign key constraint is incorrectly formed").
I've tried running both:
php artisan migrate
php artisan migrate:fresh
I also tried changing the post_category_id field to a regular integer, instead of unsigned: no difference.
Also restarted the MySQL server and Apache service, didn't make a difference.
The post_categories migration runs before the posts migration. The posts table gets created, but the foreign key doesn't.
Why is this error being thrown and how do I solve it?
This might be happening because you're trying to create a foreign key with an integer field to a big integer field. In your posts migration, instead of this
$table->integer('post_category_id')->unsigned();
do this:
$table->bigInteger('post_category_id')->unsigned();
Instead of this:
$table->integer('post_category_id')->unsigned();
Try this:
$table->unsignedBigInteger('post_category_id');
I had the same error where I wanted to link two tables, users tables and deposits tables. I tried many options but they didn't work. However, this is what worked for me on create deposits migration:
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

Laravel 5.4 create table about foreign keys were not correct

I am trying to forward engineer my new schema onto my db server, but I can't figure out why I am getting this error. I've tried to search for the answer here, but everything I've found has said to either set the db engine to Innodb or to make sure the keys I'm trying to use as a foreign key are primary keys in their own tables.And some guys said that different data types both of these column,but I am make sure that the same of both of two column data types. I have done both of these things, if I'm not mistaken. Any other help you guys could offer?
the users table migration code:
Schema::create('users', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->bigIncrements('id');
$table->unsignedBigInteger('batch_id')->nullable()->default(0);
$table->rememberToken();
$table->unsignedInteger('create_at')->nullable()->default(0);
$table->foreign('batch_id')->references('id')->on('batches')->onUpdate('cascade')->onDelete('cascade');
});
the batches table migration code:
Schema::create('batches', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->bigIncrements('id');
$table->string('name',200)->unique();
$table->unsignedInteger('create_at')->nullable()->default(0);
});

Laravel Migrations insert into table

In Laravel 5.3 within my up() function how can I insert data into another table?
I can only see things in the guide for updating columns etc
You can do it as what you do in normal Laravel code as long as that table has been created already. For example:
public function up()
{
Schema::create('this_table', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
\DB::table('that_table')->insert([]);
}
As others suggest, you should consider if it's better to move such logic into database seeders. However, I find sometimes it's better to have such logic just live inside migration files when your table have constant initial data.
FYI, Here is an open source Laravel project does this.
===========Edit 5 years later=============
I suggest anyone want to do this consider database seeders as the original answer suggested. Now Laravel have a schema:dump command that can be used for squashing your migrations. This might be useful if you have a project with many migrations. For me, I have a project with 408 migrations and it's not easy to use the schema:dump now as data filling methods in migrations will be lost.
You can insert to the table as shown below after the table is created.
DB::table('tablename')->insert([
['columnname1' => 1, 'columnname2' => 'Girl'],
['columnname1' => 2, 'columnname2' => 'Boy']
]);

One to one relationship error on can't alter table when run artisan command

I've multiple packages and users can only have one package at a time, not multiple. So, I've created one to one relationship and added a foreign key in my users table.
Here's the relevant users table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->string('role');
$table->unsignedInteger('package_id');
$table->rememberToken();
$table->nullableTimestamps();
$table->foreign('package_id')
->references('id')
->on('packages');
});
}
And here's the packages table:
public function up()
{
Schema::create('packages', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('price');
$table->integer('space');
$table->string('space_type');
$table->string('trial')->nullable();
$table->string('trial_period')->nullable();
$table->string('password_protected_links')->nullable();
$table->nullableTimestamps();
});
}
However, when I ran php artisan migrate:refresh than it appeared the following error:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'clouder.#sql-834_1
4' (errno: 150) (SQL: alter table `users` add constraint users_package_id_f
oreign foreign key (`package_id`) references `packages` (`id`))
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'clouder.#sql-834_1
4' (errno: 150)
However, I believe I've created the foreign key correctly. Is there anything else that I've made a mistake?
I've fixed the issue by myself now. The issue I was experiencing is caused by the order of the migration. The create_users_table migration comes with Laravel 5.2 out of the box as such when I've created new migrations create_packages_table the order of the create_users_table migration on the first and it was loading before the create_packages_table. As such when the query trying to create the foreign key it can't find the column on the packages table. So, simply renaming the create_users_table date to ensure it loads after the create_packages_table fixed the issue.
I hope someone may find it helpful in some days.

Categories