How to make table without primary key in Laravel? - php

I need to connect two tables in DB with relation one to one. Where 'id' from first table need to be the 'id' in the second table.
Table 1:
public function up()
{
Schema::disableForeignKeyConstraints();
Schema::create('devices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('device_type', 20)->nullable();
$table->date('purchase_date')->nullable();
$table->date('activation_date')->nullable();
$table->date('deactivation_date')->nullable();
$table->bigInteger('companyId')->unsigned();
$table->timestamps();
$table->foreign('companyId')->references('id')->on('companies');
});
Schema::enableForeignKeyConstraints();
}
Table 2:
public function up()
{
Schema::disableForeignKeyConstraints();
Schema::create('device_news', function (Blueprint $table) {
$table->integer('x', 10)->nullable();
$table->integer('y', 10)->nullable();
$table->time('time')->nullable();
$table->bigIncrements('deviceId');
$table->timestamps();
$table->foreign('deviceId')->references('id')->on('devices');
});
Schema::enableForeignKeyConstraints();
}
I never had situation like this. Is it correct or I have to change something?

To create an Eloquent model for a legacy table that has no primary key, simply add the following to your model:
/**
* primaryKey
*
* #var integer
* #access protected
*/
protected $primaryKey = null;
/**
* Indicates if the IDs are auto-incrementing.
*
* #var bool
*/
public $incrementing = false;

You should still have a $table->bigIncrements('id'); on the second table, so the table gets a PK - but you create the relation on an unsigned biginteger, which is not a primary key.
Laravel naming conventions also dictates that a relational column should be device_id and not deviceId (same goes for your primary table, it should be company_id and not companyId). Doing this will make your life much easier when you start defining your relations on your models.
Schema::create('device_news', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('device_id');
$table->integer('x', 10)->nullable();
$table->integer('y', 10)->nullable();
$table->time('time')->nullable();
$table->timestamps();
$table->foreign('device_id')->references('id')->on('devices');
});

Related

Problem with making relationships using Laravel migrations

I have problem with Laravel migrations. I want to make a relationship between two tables but
I am getting error General error: 1005 Can't create table
eshopper.prices (errno: 150 "Foreign key constraint is incorrectly
formed") (SQL: alter table prices add constraint pri ces_product_id_foreign foreign key (product_id) references
products (id) .
Here is my code. Tables are prices and products.
Prices
public function up()
{
Schema::create('prices', function (Blueprint $table) {
$table->id();
$table->float('amount');
$table->unsignedBigInteger('product_id')->unsigned()->index();
$table->foreign('product_id')->references('id')->on('products')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
}
Products
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string("title",100);
$table->text("description");
$table->timestamps();
});
}
NOTE: In my migrations products table is under prices table, I know that the first created table is prices than products and that is error.
My question is do I have to put products frst or I can keep same layout(prices first, than products) and change something in code?
it happens because the product_id field type is different from the id field in the products table, try this in the products migration file:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->unsignedBigInteger('id', true); // true here means it's auto incremental
$table->string("title",100);
$table->text("description");
$table->timestamps();
});
}
Instead of putting the constraints inside the migration file of price you can put it inside the migration file of products. Since it will create the prices table first before the products the constraints will not be created because the products table is not yet created.
/**
* This is the prices table
*
* it depends in you if you want to define the column here directly without its constraints
* the commented column is optional
*/
public function up()
{
Schema::create('prices', function (Blueprint $table) {
$table->id();
$table->float('amount');
//$table->unsignedBigInteger('product_id');
$table->timestamps();
});
}
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string("title",100);
$table->text("description");
$table->timestamps();
});
// you can define your constraints here
Schema::table('prices', function(Blueprint $table) {
$table->foreignId('product_id')
->constrained('products')
->cascadeOnDelete()
->cascadeOnUpdate();
// if you uncomment the column commented on the prices table instead of the one at above you can use this instead
$table->foreign('product_id')
->references('id')
->on('products')
->cascadeOnDelete()
->cascadeOnUpdate();
});
}
Short answer is that you MUST put products first before prices. If the whole code is still in development and have yet to get deployed, then the easiest solution is to rename the products table migration so that it has older timestamp than the prices migration has.

Remove primary key and auto-increment in database using migration in laravel

I have table with primary key and auto-increment field, I want make new migration to drop primary key index and also remove the auto increment field. How can i achieve this.
I created new migration as
public function up()
{
Schema::table('tbl_message_read_state', function (Blueprint $table) {
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('tbl_message_read_state', function (Blueprint $table) {
$table->dropPrimary('message_id');
$table->unsignedInteger('message_id');
});
}
It gave me error in command as [Illuminate\Database\QueryException]
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'message _id' (SQL: alter table tbl_'message_read_state' add 'message_id' int unsigned not null)
Whats Wrong ?????
Blueprint class offers dropPrimary methods that allow you to remove primary key.
public function down()
{
Schema::table('table', function (Blueprint $table) {
$table->dropPrimary();
$table->unsignedInteger('id'); // for removing auto increment
});
}
This did it for me:
Schema::table('table_name', function (Blueprint $table) {
// Make AI field `id` unsigned otherwise SQL
// will throw error when you try to remove it
$table->integer('id')->unsigned()->change();
$table->dropColumn('id');
// If there was a foreign on message_id, make sure to remove it
$table->dropForeign('table_name_message_id_foreign');
$table->dropPrimary('message_id');
$table->dropColumn('message_id');
}
The dropPrimary method only removed the primary key, not the column. You would have to do:
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('tbl_message_read_state', function (Blueprint $table) {
$table->dropPrimary('message_id');
$table->dropColumn('message_id');
$table->unsignedInteger('message_id');
});
}
Or instead of dropping and re-creating the column, you can use change in Laravel 5.
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('tbl_message_read_state', function (Blueprint $table) {
$table->dropPrimary('message_id');
$table->integer('message_id')->unsigned()->change();
});
}
You can try this
$table->dropPrimary('id_primary');
Drop the primary key:
$table->dropPrimary( 'id' );
Reference
Use a simple drop column
$table->dropColumn('id');
https://laravel.com/docs/4.2/schema#dropping-indexes
tabel_name
column
index $table->dropPrimary('users_id_primary');

laravel : seeder with foriegn keys

in my database i have already tables namely: notifications table, statuses table, they have many to many relation, that is why i have a pivot table called notification_status. i created them with migrations and seed them with a seeder, all works fine. now i realize that i need one extra table which has many to one relation with notifications table(natification->hasMany->alertfrequency). when i tried to migrate it, it did allow me to do so.
here is my notification table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateNotificationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('notifications', function (Blueprint $table) {
$table->increments('id');
$table->string('website_url');
$table->string('email');
$table->string('slack_channel');
$table->string('check_frequency');
$table->string('alert_frequency');
$table->string('speed_frequency');
$table->boolean('active');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('notifications');
}
}
and the alert frequency table, the new table i want to add,
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAlertFrequenciesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('alertFrequencies', function (Blueprint $table) {
$table->increments('id');
$table->integer('notification_id');
$table->foreign('notification_id')
->references('id')->on('notifications')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('alertFrequencies');
}
}
when i tried to add i get the following constrain
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `alertFrequencies` add constraint `alertfrequencies_notification_id_foreign` foreign key (`notification_
id`) references `notifications` (`id`) on delete cascade)
any one with a idea or suggestion. i appreciate all idea and suggestions.
From #AlexeyMezenin's answer, update based on Documentation:
Replace
$table->integer('notification_id')->unsigned();
with
$table->unsignedInteger('notification_id');
First thing you should do is to add unsigned(), because id is unsigned too:
$table->integer('notification_id')->unsigned();
If it'll not help, divide key creation and adding a foreign key constraint:
Schema::create('alertFrequencies', function (Blueprint $table) {
$table->increments('id');
$table->integer('notification_id')->unsigned();
$table->timestamps();
});
Schema::table('alertFrequencies', function (Blueprint $table) {
$table->foreign('notification_id')->references('id')->on('notifications')->onDelete('cascade');
});
You need to migrate notifications table prior to alertFrequencies table as notification_id of alertFrequencies is referencing id of notifications table.
And you need to change $table->integer('notification_id'); to $table->integer('notification_id')->unsigned(); as you cannot accept minus ids as foreign key
And also make sure you have set your table engine set to InnoDB in your `config/database.php'.
$table->engine = 'InnoDB';

How to make foreign key same int type ?

I have the following migration file declared in laravel:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products' , function($table){
$table->increments('id');
$table->integer('category_id');
$table->string('title');
$table->text('description');
$table->decimal('height' , 6 , 2);
$table->decimal('width' , 6 , 2);
$table->decimal('length' , 6 , 2);
$table->string('color');
$table->string('material');
$table->timestamps();
});
Schema::table('products' , function($table){
$table->foreign('category_id')->references('id')->on('categories');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('products');
}
}
now when i run php artisan migrate
i get an error , because the id in categories is int(10) and the categories_id I.E.
$table->foreign('category_id')->references('id')->on('categories');
is int(11) how do i make both int(10) ?
I would guess that your previous migrations were run on a previous version of Laravel. If that's the case, you can simply modify the column type of categories.id to int(11) directly in the DB.
Otherwise, you could use a Raw Query to add the column using INT(10).
To confirm the hypothesis that a version change caused this, you could run ALL migrations in an empty DB and see if you have the same issue.
Schema::table('products', function($table)
{
$table->integer('id, 10');
});

Handling foreign checks in Laravel 5 migrations

I have a calls table with user_id column and a foreign key constrain. So, user_id is related to users table.
I made a migration which deletes the column and foreign key constrain. The up method works fine. However, when it comes to down it breaks down because I add a user_id column and then restore the constrain, but the values in the column have nothing to do with real data so I got 150 MySQL error.
I've found a solution which didn't work for me. The solution is to temporarily disable foreign key constrains. Here is my migration file:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveUseridFromCalls extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('calls', function(Blueprint $table)
{
$table->dropForeign('calls_user_id_foreign');
$table->dropColumn('user_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
\DB::statement('SET FOREIGN_KEY_CHECKS = 0');
Schema::table('calls', function(Blueprint $table)
{
$table->integer('user_id')->unsigned();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('set null');
});
\DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
}
But I still get the same error.
So, the questions are:
What would you do if you need to remove user_id from columns table as it's not needed anymore, however you have to write the down method as well as up?
Why disabling foreign key checks doesn't work?
I use InnoDB as table type for all my tables.
You can simply use onDelete('cascade').
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('calls', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade'); // use 'cascade'
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('calls');
}
}
onDelete('cascade') tells Laravel to delete a calls row when it's corresponsding foreign key user_id is deleted.
I had the same problem and fixed it by separating migration into several files. First one creates the table, the others add columns for the keys and the keys themselves.
After that everything starts working like a charm.
To check foreign key in table while dealing with migration can be as follow:
$keyExists = DB::select(DB::raw('SHOW KEYS FROM TABLE_NAME WHERE Key_name=\'YOUR_FOREIGN_KEY_NAME\''));
if(!$keyExists){
$table->foreign('app_id')
->references('id')
->on('apps')
->onDelete('cascade');
}

Categories