Laravel Many to Many Pivot on existing Pivot - php

I have a situation in Laravel 5.1 where I would like to add a many-to-many relationship to an existing relationship. According to the diagram below, I already have all the items in green working.
The issue is that since there isn't a primary key on the issue_person table, I don't know how to add a many-to-many relationship to Users. Does anyone know how I would go about accomplishing this?

So it appears that a simple answer to this is to write a migration that adds a primary key to the original issue_person pivot table, and then set up a many-to-many relationship between issue_person and user using the position_user table.
My migration looks like this:
public function up()
{
Schema::table('issue_person', function (Blueprint $table) {
$table->increments('id');
});
}
public function down()
{
Schema::table('issue_person', function (Blueprint $table) {
$table->dropColumn('id');
});
}

Related

I have two pivot tables but I want to insert into one when I run a function, how do I do this?

So, as the title says, I have two pivot tables in my Laravel project (I am still new to Laravel). My project is an Instagram clone and I have made the like function, which uses one of the two pivot tables I made and now I'm trying to make a "Save" function, similar to the actual Instagram app where people can save posts and view them at a later time. The problem is, when I check my tinker and do:
As you can see, it looks like the likes and saves are using the pivot table for likes, I have not inserted anything into the pivot table for saves yet. Here are my migrations
For likes:
Schema::create('post_user', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('post_id');
$table->timestamps();
});
And for saves:
Schema::create('post_user_saves', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('post_id');
$table->timestamps();
});
I'm aware that they are literally the same but, just like the Instagram app, a user can like a post without saving it and vice-versa and they can also like and save it at the same time. I want to insert into the post_user_saves when I click a button. Here are pics of my database as well, as you can see the post_user_saves table is empty while post_user is not, meaning that tinker is getting the pivot data from post_user
and lastly, here are the codes from my model:
public function likes()
{
return $this->belongsToMany(Post::class);
}
public function saves()
{
return $this->belongsToMany(Post::class);
}
EDIT:
here is my store method for the likes:
public function store(Post $post){
return auth()->user()->likes()->toggle($post->id);
}
I don't have the store method for my saves yet but my plan is to make it the same as the one above hence why I need to be able to store to post_user_saves.
If your relationships are correct you can use attach() to save to the pivot:
auth()->user()->likes()->attach(auth::id(), ['column' => 'value']);
The reason your save is updating the same table is because you are pretty much using the exact same relationship so eloquent doesn't know about your post_user_saves table what you would need to do is Create a model Save() then rename your migration to save_users and update your relationship accordingly.

Laravel 7 physical relationship between tables not present

I followed a tutorial about many-to-many relationships with Laravel (7 in my case).
The result is good, I learned a lot, but what I find strange is that I do not have physical relationships between the different tables.
I created a relationship many to many, which should link 3 tables, products, categories and products_categories
My questions :
1- Is it essential to have a physical relationship in the schema of the database?
2- How can I make these relationships appear in my diagram?
Here is a current photo of the database schema :
In this database, I have links between tables :
The Laravel relationships are not the same as your database relationships (MySQL, or others).
You don't need to have a database relationship to have your application working. it is really depending on what you are trying to achieve.
If you want to see the relationships between your tables, make sure to specify the foreign keys in your migration Schema (https://laravel.com/docs/7.x/migrations#foreign-key-constraints) such as:
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
For pivot tables you can also use a migration Schema as follow:
Schema::table('category_product', function (Blueprint $table) {
$table->unsignedBigInteger('category_id');
$table->unsignedBigInteger('product_id');
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('product_id')->references('id')->on('products');
});

Add cascade/delete functionality to existing migration

I have 2 tables in my database. One for Courses and one for Course Chapters.
The migration for the courses looks like this:
Schema::create('courses', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
The migration for the chapters looks like this:
Schema::create('course_chapters', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('course_id');
$table->timestamps();
});
I want the course and the chapter to cascade down, so when i delete a course, the chapter also will be deleted.
Some examples i saw make use of deleting the foreign key but I never signed my column as a foreign key.
For example, normally, I could:
$table->dropForeign('course_id');
$table->foreign('course_id')
->references('id')->on('courses')
->onDelete('cascade');
How can i accomplish this in a (preferably) new migration and on what table should i add the foreign key?
This as it is should go on your course_chapters table:
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
You don't need to add $table->dropForeign('course_id'); because that will drop the foreign key from the column.
NOTE: and this:
$table->unsignedInteger('course_id');
Should be this:
$table->unsignedBigInteger('course_id');
Because it will throw an error of using different data types.

delete cascade laravel not working

I have a problem with delete using laravel 5.4
I have 3 tables: Users, Posts, Vechicles
User hasMany Posts
Vehicle belognsTo Post
Post hasMany Vehicles
...anyway...when creating the schema for the vehicle table, i use 2 foreign keys:
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->foreign('post_user_id')->references('user_id')->on('posts');
When i want to delete a post, all the vehicles that are related to the post to be deleted....but is not working (it gives an error about constraint)
Can someone tell me what i am wrong? it is that i am using 2 foregin keys?
check this
$table->engine = "InnoDB";
Using one foreign key solve the issue:
Schema::create('vehicles', function (Blueprint $table) {
$table->increments('id');
$table->string('mark');
$table->string('model');
$table->integer('weight');
$table->string('vehicle_state');
$table->integer('post_id')->unsigned();
$table->integer('post_user_id')->unsigned();
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
});

Laravel migration foreign keys

I'm trying to build some relationships in Laravel, i'm a little confused about relationships and migrations. Here is a simple example of what i'm doing:
Users -> has_many -> Cats
So my Users migration file has a relationship to Cats like so:
$table->foreign('cats_id')->references('id')->on('cats')
But when I run my migration, I get:
Error: relation cats does not exist...
Do I need to build the Cats table before the Users table?
Do I also need to specify the foreign relation between the two, or if the models contain "hasMany" and "belongsTo" wouldn't Laravel build those relationships automatically on migration?
Do I actually need migrations?
You can't reference a table that not exists. It has nothing to do with Laravel or Eloquent, it's (My)SQL thing.
First create the parent table users, then the child table cats referencing the first:
$table->foreign('user_id')->references('id')->on('users')
this is how User hasMany Cat would look like. cats table has foreign key referencing users table, not the other way around like you tried.
You need to set the foreign key to the table where the 'many' are.
$table->foreign('id')->references('cats_id')->on('Users')
You need to make sure that
Table 'Users' exists before you create table Cats (Or any other table that is referenced)
Column 'id' exists before you create the foreign key. (Or any other column that is referenced)
A quite bulletproof solution for me is to setup the tables with a first migration eg
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->timestamps();
$table->string('cats_id');
});
//and
Schema::create('cats', function(Blueprint $table)
{
$table->increments('id');
$table->timestamps();
$table->string('cat_name');
});
}
in one migration file and then I create another migration file that runs in the end and creates all the foreign keys for all migrations that were running before:
public function up()
{
Schema::table('cats', function(Blueprint $table)
{
$table->foreign('id')->references('cats_id')->on('users');
});
}
You can also choose what should happen to your cats table on update or delete of a user by adding eg
->onUpdate('CASCADE')->onDelete('CASCADE');
to the $table->... line
You will have to run the migration for cats table and create that table before you can associate it with users table.
Foreign key relation will be helpful when you are required to do cascade delete or update. Also an insert like the following will be easier for you with the cats relationship set.
$user = User::find(1);
$cats = array(
new Cat(array('name' => 'Kitty')),
new Cat(array('name' => 'Lily')),
);
$user->cats()->save($cats);
When specifying a relationship on User Model the Cat model also needs to exist.
In migration
Users
$table->foreign('cats_id')->references('id')->on('cats');
Cats
$table->foreign('user_id')->references('id')->on('users');
Now you force integrity on database level.
Migrate
run the migration using php artisan migrate
Next step is to add the integrity on you Model
Model
User.php
public function cats()
{
return $this->hasMany('Cats');
}
Cat.php
public function user()
{
return $this->belongsTo('User');
}

Categories