I have an issue with the soft deleting of records in a pivot table in my Laravel 5.4 application. In my Records.php I have a association with teams like:
public function teams()
{
return $this->belongsToMany(Team::class)
->withTimestamps();
}
When I update a record, I use the sync method to easily add/remove teams. The teams are selected in a multiple select form field and updated like:
$record->teams()->sync($request->get('teams'));
When adding new teams, the pivot table DOES update the created_at and updated_at. But when REMOVING a pivot table record, the whole row is deleted and the deleted_at is not set? How can I get the soft deleting to work in a pivot table.
Related
I have an application that contains 2 models: User and Event
There's a many to many relationship between them and I am using a pivot table (called participants). I need to insert the data into the pivot (participants) table manually (specify each column's value).
I can't use the relationship insert, because I am leaving the user_id column blank. (Therefore it won't be a "relationshipped" column.) Any ideas how to make this scenario real, please?
I would like to sync the data instead of attach the data to the particular relationship.
Pivot relation UserModel code
public function carts(){
return $this->belongsToMany(Product::class,'user_carts')->withPivot('quantity');
}
The attach code is
User::find(1)->carts()->attach($s,["quantity"=>1]);
The sync code is
User::find(1)->carts()->sync($s,["quantity"=>1]);
When I try to compile the sync, those pivot relation that matched user_id = 1 does not have the "1" in its respective quantity column.
If I would like to achieve the sync function without using attach, how can I do it because the attach() will create multiple redundant data in my database.
You have to pass key values in the sync method.
Assuming $s is the id (key) to be synced:
User::find(1)->carts()->sync([$s => ["quantity"=>1]]);
Lets say I have a user and appointment table.
users - id, name, email, type(doctor/patient)
appointment- id, doctor_user_id, patient_user_id
My user table data-
And my appointment table data-
I could make two belongs to relationships from appointment with user table.
As you can see my appointment table, I want to store only user that type is doctor to doctor_user_id and patient to patient_user_id. But in this case i can add any user id to doctor_user_id field either it is doctor or patient but i want to add only user id as doctor_user_id only if its type is doctor.
I know how to achieve this with two different table but I was wondering is there any way to achieve this with single user table, Thanks.
Yes, you can achieve this by creating one user table only.
Create 2 foreign key for the "doctor_user_id" and "patient_user_id" of appointment table which references to User table.
You can use two belongsToMany() relationships and use the table as I pivot:
public function doctors()
{
return $this->belongsToMany(User::class, 'appointment', 'patient_user_id', 'doctor_user_id');
}
public function patients()
{
return $this->belongsToMany(User::class, 'appointment', 'doctor_user_id', 'patient_user_id');
}
If you'll use the appointment table a lot, you can also add two hasMany() relationships to the Appointment model and two belongsTo() relationships to the User model. So, you could use belongsToMany(), hasMany() and belongsTo() relationships simultaneously for in this case.
I have two tables. Table reports
report_id | user_id | item_id
and reports_messages
report_id | user_id | item_id | messages
I want when I delete report_id on reports all related rows which matching report_id in reports_messages to be deleted too.
In my ReportMessages Model I have this relation
public function reports(){
return $this->belongsTo('App\Report');
}
public function item(){
return $this->belongsTo('App\Item', 'item_id', 'id');
}
In Report model
public function reportedItem(){
return $this->belongsTo('App\Item');
}
public function user(){
return $this->hasOne('App\User', 'id', 'user_id');
}
So far I've tried this solution founded here on SO
public function destroy($report_id){
Report::destroy($report_id);
ReportMessages::find(1)->reports()->where('report_id',$report_id)->delete();
return redirect()->route('user.ports');
This deletes only in reports.. doesn't delete related report_id's in pivot table.
}
Laravel has the functions detach and attach to deal with pivot tables.
So you can do this to remove the record in the pivot table:
ReportMessages::find(1)->reports()->detach($report_id);
This will however not remove the row in the reports table because it could still be linked to another object.
Update:
So, I just noticed, you don't have pivot tables, you only have two models that are linked.
You don't have to load the reports() relation in your query to remove the ReportMessages, you can just do it like this:
Report::destroy($report_id);
ReportMessages::where('report_id',$report_id)->delete();
This will remove the report, and all corresponding reportmessages.
I'm know I'm late but the best option with this kind of relationship, it is best to define foreign keys to particular linking tables in your table " reports_messages" like below
>
$table->integer('report_id')->unsigned()->index();
$table->foreign('report_id')->references('id')->on('reports')->onDelete('cascade');
$table->integer('message_id')->unsigned()->index();
$table->foreign('message_id')->references('id')->on('messages')->onDelete('cascade');
When you do something like this, the pivot table data will be removed as long as either message or report is deleted from database without a need of detaching methods.
Best option in case message or report has relationship with other data,such that when data is deleted message should be deleted automatically, in this case we do not have to worry about detaching data again
To remove a many-to-many relationship record, use the detach method. The detach method will remove the appropriate record out of the intermediate table; however, both models will remain in the database:
ReportMessages::find(1)->reports()->detach($report_id);
official documentation is here
I am using Laravel 5.2.
I have 3 tables: book, user and book_user (the pivot table).
I want to use soft deletes on my pivot table. When I attach a book to a user, the relationship is inserted into the book_user table. However when I detach this relationship, the record in the pivot table is deleted even though I added use SoftDeletes to the pivot table model.
How can I implement soft deletes for the records in my pivot table when I attach or detach?
I didn't try it using soft delete with pivot table but you're saying that it doesn't work.
Just an idea, maybe you can use sync instead of detach like this;
Before that you need to add deleted_at column to book_user table as DATETIME instead of TIMESTAMP. Because new version of MYSQL doesn't support NULL for TIMESTAMP type.
Soft Deleting
$user->books()->sync(array(1 => array('deleted_at' => DB::raw('NOW()'))));
Getting
Also you can put a constraint on the Eager Load:
public function books()
{
return $this
->hasMany('Book')
->whereNull('book_user.deleted_at');
}