delete record related through two field - laravel

I have two models:
model 1
field id, field_a, field_b
model 2
id2, field_a, field_b
on $model1->delete() I would like to delete also $model2 where field_a and field_b are the same of $model1 (both of them)
Example
model1
1, 2, 5
model2
1, 2, 4
2, 3, 5
3, 2, 5 (to be deleted)
I don't know if this could be helpful
Automatically deleting related rows in Laravel (Eloquent ORM)

Register a delete event on model 1 that deletes model 2 where the values match.
In model 1 add the following...
public static function boot()
{
parent::boot();
static::deleted(function($model1) {
Model2::where('field_1', $model1->field_1)->where('field_2', $model1->field_2)->delete()
});
}
Now whenever you delete model 1, model 2 with matching attributes are also removed.

Just find and delete the rows from model2 where the column values are similar.
Model2::where('field_a',$model1->field_a)->where('field_b',$model1->field_b)->delete();
$model1->delete();
Here, Model2 is the class of the Second model.

Related

Laravel 8 Sum column of related table

I have 2 tables, 'Invoice table', and related 'linesInvoice' table.
To simplify it, I will say that the invoice lines table has only the invoice_id field for the relationship and total for the price.
Now, I need to get last invoices, with his totals (totals, is the sum of column 'total' in every line).
I've tried many examples, but none works for me correctly.
Controller:
$lastInvoices = Invoice::latest()
->limit(10)
->with(['invoiceLines'])->get();
Model for relation
public function invoiceLines()
{
return $this->hasMany(InvoiceLines::class, 'invoice_id');
}
The result that I want for example looks like:
[
Invoice_id => 1
total => 500 //Sum of totals in lines of invoice 1
],
[
Invoice_id => 2
total => 300 //Sum of totals in lines of invoice 2
],
I guess I could go through all the invoices and lines in foreachs and make the sum. But I hope it can be done in the same query
You can use withSum method. This method accept the relation method as first argument and column to sum as second argument
$lastInvoices = Invoice::latest()
->limit(10)
->withSum('invoiceLines','your_column_name')
->with(['invoiceLines'])->get();
Laravel 8^
Invoice::with('invoiceLines')->latest()->first()->invoiceLines()->sum('totle');
totle colme table invoiceLines

How to minimize "where()" on Laravel query builder. If all table columns are all the same values

Is there a way to minimize calling ->where() on laravel query builder?
Sample Table:
name
item1
item2
item 3
David
0
0
0
David
1
1
2
David
1
2
2
I want to remove a specific record with all the table columns containing 0 value without removing the other records.
My query is this.
DB::table('users')->where('name', 'David')
->where('item1', 0)
->where('item2', 0)
->where('item3', 0)
->delete();
Is there a way to minimize calling->where()? Just like in whereIn('columns',[1,2,3,4]) but in columns.
Pass an array of conditions to the where function. Each element of the array should be an array containing the three arguments typically passed to the where method:
$conditions=[
['name','=', 'David'],
['item1','=',0],
['item2','=', 0],
['item3','=', 0],
]
DB::table('users')->where($conditions)->delete();
Ref: https://laravel.com/docs/8.x/queries#where-clauses

Laravel : How to show a multiple rows from DB in one row in view blade

In my Laravel project, I have a multiple rows in my DB table, similar to each other in every thing except ID, other column called stage
Stages table
ID
name
1
first
2
second
3
third
subjects Table
ID
name
stage_id
1
English
1
2
English
2
3
English
3
I need to show em in a blade like this
#
name
stage
1
English
first, two, three, etc
I already have the relations in my modals, and I am already showing them in my blade by loop, but I just want to group the rows by name and show the different stages
I hope that I explained the case well, I am not very good at explaining
Updates : before editing I wrote a dummy data now I hope I explained the issue in more details
The project idea is that you can create more than faculty
and every faculty has Stages and sections and every section has specialties and every specialty has subjects
now about subjects and stages
user can create subject like English and make it available to the first stage and 2nd and third ..etc ( the available stages in this faculty)
The Stages belongs to Faculty
The Subjects belongs to Stage
so the relations are
Subject Model
public function stage()
{
return $this->belongsTo(Stage::class);
}
Stage Model
public function subjects()
{
return $this->hasMany(Subject::class);
}
As you have "English" Multiple Times, you should have a subject Table :
Stages table
ID
name
1
first
2
second
3
third
Subject table
ID
name
1
English
stage_subject Table :
ID
stage_id
subject_id
1
1
1
1
2
1
1
3
1
Subject Model
public function stage()
{
return $this->belongsToMany(Stage::class);
}
Stage Model
public function subjects()
{
return $this->belongsToMany(Subject::class);
}
Then in your foreach:
#php($subjects = Subject::with('stages')->get())
#foreach($subjects as $subject)
{{ $subject->id }} | {{$subject->name}} | {{$subject->stages->pluck('name')->implode(', ')}}
#endforeach
If you don't / can't do a pivot table, then you can use collection :
#php($subjects = Subject::with('stages')->get())
#foreach($subjects->groupBy('name') as $name => $subjects)
{{ $subjects->first()->id }} | {{$name}} | {{$subjects->pluck('stage.name')->implode(', ')}}
#endforeach

Laravel computed field on the relation's of a model like a model attribute

I have a model for Flights.
The Flight have a relationship with payments_log.
In the payments_log table there are two fields: amount and type(Input/Output or add/sub).
I want to add a field on the Flight model for example Total_amount.
The total_amount on the Flight model will be a field that computed from relationship.
type amount
I 5.0
I 10.0
O 2
Total_amount = I+I-O = 13
What is the best practice?
Create a accessor method on your Flight model that sums the amount column from the logs table:
public function getTotalAmountAttribute()
{
// Sum log records of type I (add)
// and substract the sum of all log records of type ) (sub)
return $this->paymentsLog()->where('type', 'I')->sum('amount') - $this->paymentsLog()->where('type', 'O')->sum('amount');
}
Then you can access it using:
$flight->total_amount;

Does Eloquent relation sync also remove?

When updating a model and I sync a relationship, if I don't pass in all the ids that already exist, will that relationship be removed?
You decide: sync has 2nd parameter that defaults to true and is responsible for detaching:
$model->relationship()->sync([1,2,3]);
$model->relationship()->sync([4,5,6]); // attached [4,5,6], detached [1,2,3]
$model->relationship()->getRelatedIds(); // [4,5,6]
// but:
$model->relationship()->sync([4,5,6], false); // attached [4,5,6], detached []
$model->relationship()->getRelatedIds(); // [1,2,3,4,5,6]
The answer is Yes it does. I could not find any documentation that in fact stated that.
lets say you have 2 tables: "authors" and "books", with a pivot table "book_authors".
when creating a new author:
$author_id =2;
$author->books()->sync(array(1,4,5,15));
Now you have a 4 entries in that pivot table "book_authors":
author_id book_id
2 1
2 4
2 5
2 15
Now update:
$author_id =2;
$author->books()->sync(array(1,15));
now "book_authors" is:
author_id book_id
2 1
2 15

Resources