The many to many relationship works. The original working migration:
Schema::table('tag_topic', function (Blueprint $table) {
$table->integer('topic_id')->unsigned()->index();
$table->integer('tag_id')->unsigned()->index();
});
I want the pivot table items to be deleted when referenced items are deleted. The new migration:
Schema::table('tag_topic', function (Blueprint $table) {
$table->foreign('topic_id')->references('id')->on('topics') ->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});
The pivot table row items are not cascaded deleted.
Update:
I dropped the table and rewrote the the migration, but still the pivot rows are not cascade deleted:
Schema::create('tag_topic', function (Blueprint $table) {
$table->integer('topic_id')->unsigned();
$table->integer('tag_id')->unsigned();
$table->foreign('topic_id')->references('id')->on('topics')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});
This code deletes the pivot table rows:
$tag = Tag::where('id', $tag->id)->get()->first();
$Tag->topics()->detach();
Try dropping your old indexes before applying the foreign key constraints.
Schema::table('tag_topic', function (Blueprint $table) {
$table->dropIndex(['topic_id']);
$table->dropIndex(['tag_id']);
$table->foreign('topic_id')->references('id')->on('topics')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});
Related
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.
I'm creating a table where I want to use the ID from this table "menu_items" to be added in another table
Table one: menu_items
Schema::create('menu_items', function (Blueprint $table) {
$table->id('menu_level_item_id');
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
Table 2 products
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->integer('menu_level_item_id');
$table->timestamps();
});
My aim of doing this is that I can then create a relationship between the 2 tables as they have the same key?
Is there a different approach I can take? Should I create a unique key when creating a menu item and then add this to the second table?
Thank you.
Basically Laravel Eloquent do the key handling. When you have two tables which both has as key the name id, this is not a problem. Name the keys in the relation table just like this
table1_id
table2_id
Laravel will handle this in Eloquent. You are also able to name the two columns in the relation table to what ever you want. You could define it for the relation in Eloquent. E.g.
public function otherModel () {
return $this->belongsToMany('App\Models\OtherModel', 'table_name', 'this_model_id', 'other_model_id');
}
Please have a look into:
Laravel Relationship Documentation
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
table->timestamp();
});
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->unsignedBigInteger('menu_level_item_id');
$table->timestamps();
$table->foreign('menu_level_item_id')->references('id')->on('menu_items');
});
Basically, I have 2 tables in my database: Games and Teams.
Every Game must have 2 teams, so it's a two-to-many relationship.
Should I use 2 foreign keys in my Games table pointing to the 2 teams in the Teams table and have a one-to-many relationship, or use many-to-many relationship with a third table to link the games and teams table?
Im using Laravel 6.5 for the project, so I guess im using Eloquent to implement it.
Schema::create('games', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('team_a_id');
$table->foreign('team_a_id')->references('id')->on('teams')->onDelete('restrict');
$table->unsignedBigInteger('team_b_id');
$table->foreign('team_b_id')->references('id')->on('teams')->onDelete('restrict');
$table->unsignedInteger('team_a_score');
$table->unsignedInteger('team_b_score');
$table->string('status');
$table->boolean('finished');
});
Schema::create('teams', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('abbreviation');
$table->string('country');
$table->timestamps();
});
This are the two tables I have created by now, is this the correct way to implement it?
Use a Many to Many Relationship. In that case the Game Modal could have multiple Teams and vice-versa.
Hence the migrations would be like:
Schema::create('games', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('status');
$table->boolean('finished');
});
Schema::create('teams', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('abbreviation');
$table->string('country');
$table->timestamps();
});
Schema::create('game_team', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('game_id');
$table->integer('team_id');
$table->unsignedInteger('score');
$table->timestamps();
});
I have two tables rta_list and rta_reg_company. I have a column count in rta_list table.
Schema::create('rta_list', function (Blueprint $table) {
$table->increments('rta_id');
$table->string('rta_name');
$table->string('rta_address');
$table->string('rta_phone');
$table->string('rta_email')->unique();
$table->integer('count');
$table->timestamps();
});
Schema::create('rta_reg_company', function (Blueprint $table) {
$table->increments('company_id');
$table->integer('rta_id')->unsigned();
$table->foreign('rta_id')
->references('id')
->on('rta_lists')
->onDelete('cascade');
$table->string('company_name');
$table->string('company_isin');
$table->string('company_script');
$table->string('company_address');
$table->string('company_phone');
$table->string('company_email');
$table->timestamps();
});
I want to increase the value of count of rta_list table by rta_id when I add new RTA Registered Company. For eg: if i add one company then, The value must be added in rta_reg_company table and count must be 1 in count column in rta_list table.
Also also how to show the count value by rta_id in view..
Help Needed.....
you can use laravel Observer to raise an event on a model creation.then you can update as below on model Observer:
public function created(Company $company)
{
DB::table('rta_list')->increment('count');
}
I have 2 tables created like so :
Schema::create('educations', function(Blueprint $table){
$table->increments('id');
$table->string('title');
$table->date('from_date');
$table->date('to_date');
$table->string('summary');
$table->integer('cv_id')->unsigned();
$table->foreign('cv_id')->references('id')
->on('cvs')
->onDelete('cascade')
->onUpdate('cascade');
$table->timestamps();
});
And they are linked to another table :
Schema::create('cvs', function(Blueprint $table){
$table->increments('id');
$table->integer('student_id')->unsigned();
$table->foreign('student_id')->references('id')
->on('students')
->onDelete('cascade')
->onUpdate('cascade');
$table->string('summary');
$table->timestamps();
});
The problem is, whenever i call this line :
$student->cv->delete();
It will drop the cv but not the other attributes in tables related to it.
What am i missing ?
That's not how it works. cascade means that when you'll detele some CV from cvs table, all rows with same cv_id will be deleted from educations table. You can't expect the whole table will be deleted.