laravel tables with relationship and insertion - laravel

I have 4 tables
Customers : with data of customers. this table hasMany(Refunds)
Refunds: with data of various request. this table belongsTo(Customers) AND belongsToMany(Services)
Services: with list of services. this table belongsToMany(Refunds)
Refunds-Services: bridge table for refunds and services
I have a form that must insert datas in the correct table.
public function storeRefunds(RefundsPost $request){
DB::beginTransaction();
$customers = Customers::create($request->all());
$refunds = $customers->refunds()->create([
'date_ref' => request('date_ref'),
'status_ref' => request('stato'),
]);
$tipo = $request->input('tipo', []);
$importo = $request->input('importo', []);
$refunds = Refunds::create($request->all());
for ($i=0; $i < count($tipo); $i++) {
if ($tipo[$i] != '') {
$refunds->services()->attach($tipo[$i], [
'services_id' => $tipo[$i],
'services_amount' => $importo[$i]
]);
}
}
return redirect("/");
}
with this code i can insert all datas in correct tables but i cannot find ID connection in the Refunds table. Two different ID are created in Refunds table. second created id in the Refunds table not connected to any customer (0) but connected to the list of services choosen.
How can i do?
Thx

You need to debug your code. First Refund creates in this line $refunds = $customers->refunds()->create and it's belongs to Customer, second Refund creates here : $refunds = Refunds::create($request->all()); and it's doesn't relate to any Customer, but relates to Service (you do this in for loop). By the way, your tipo input is not multiple (it should be with [] if you expects it can be more than one value) and for loop is senseless in this sutiation.
Delete one of Refunds::createmethods, bring your data to expected view and use createMany() method.
More info in Laravel docs : https://laravel.com/docs/7.x/eloquent-relationships#the-create-method

Related

Access model attributes in Laravel update query

I have an UPDATE query that I'm struggling with, basically want to access its column during update.
I have a users table (with existing data) with a column address where a string value is added. To make things cleaner I created a separate table locations to store all the addresses and set up foreignId('location_id') on the users table.
locations table is then filled by getting unique address values from users table.
Now I need to update the location_id of existing users.
**This is what I tried:**
$locations = Location::get(); // only about 100 results are there
User::query()
->whereNotNull('address')
->update([
'location_id' => $locations->firstWhere('street', DB::raw('address'))->id
]);
But the above query is not updating the column "location_id" on users table.
Model Relationships
// On Location Model
public function users()
{
return $this->hasMany(\App\Models\User::class);
}
// On User model
public function location()
{
return $this->belongsTo(\App\Models\Location::class);
}
You issue is that DB::raw('address') probably does not return anything so my suggestion is to update the whole query.
$locations = Location::all();
User::whereNotNull('address')->each(function($user){
$locations = $locations->where('name', $user->address)->pluck('id');
$user->attach($locations);
})
The above query will get all the locations first, then we get all the users who have an address and for each of those users we first find all the locations with that address, get the ids of those locations, add attach those locations to the user.

store data from conroller to database in laravel

Am getting data from two tables banks one has bank details and another has cheques. the cheques table has bank_id column where by i loop through and calculate the totals of each bank.
How can i store the data in a table instead of it staying in a variable.
I have a controller to calculate the totals;
$banks_data = Bank::all();
$banks_totals = [];
foreach ($banks_data as $bank){
$totals = InsuranceCheque::where('bank_id', $bank->id)->sum('amount');
array_push($banks_totals,
[
'id'=>$bank->id,
'name'=> $bank->name,
'description' =>$bank->description,
'amount'=>$totals,
'created_at'=>$bank->created_at,
]);
}
but how will i be able to access the data in a different controller?
Which table do you want to save it to? Assuming you have a model BankTotal that handles the table bank_totals, you can do this
$banks_data = Bank::all();
$banks_totals = [];
foreach ($banks_data as $bank){
$totals = InsuranceCheque::where('bank_id', $bank->id)->sum('amount');
array_push($banks_totals,
[
'id'=>$bank->id,
'name'=> $bank->name,
'description' =>$bank->description,
'amount'=>$totals,
'created_at'=>$bank->created_at,
]);
}
BankTotal::insert($bank_totals);//Bulk insert
I did not understand the second part of the question on "but how will i be able to access the data in a different controller?"
But you can access the data from another controller by querying the model:
BankTotal::all();

After Update, The data from another Table will be deleted

I Have two different database table named Customers and Change_info_request
customers will request of changing their infomation and it will stored in Change_info_request and me the admin will be the one who will approve for changing information.
after the update the information inside the Change_info_request will transfer to the Customers table and the data inside the Change_info_request will be deleted .
And that's is my problem, i want to do it in the same controller like this
UpdateRequest
public function UpdateRequest(ClientUpdate $request){
$res = Customer::where('id', $request->id)
->update([
'first_name' => $request->new_first_name,
'last_name' => $request->new_last_name,
'birthdate' => $request->new_birthdate,
'gender' => $request->new_gender,
'pending_update_info' => 2,
]);
if($res) {
return response()->wrap($res);
} else {
return response()->wrap(["message" => "something went wrong!"]);
}
}
How will i delete the info from Change_info_request inside this controller ?
Sorry for the wrong grammar and im only a student that studying laravel.
you have id of that row in Change_info_request table right?
i have done this before this was my way:
i store new information in my table called edit-user (just like your Change_info_request ) and when i show them in admin dashboard i have their id!
when admin click on approve button it will send the id of that row to some function!
in function i find the row in edit-user table with id that i have, and replace my new data in my users table (your Customers table) and when i finished replacing data i will delete data from edit-user with that id!
Change_info_request::find('customer_id', $id)->delete();
with id of that row in edit-user(your Change_info_request table) table you can do anything
and of course your in Change_info_request table you should have user_id field
good luck!
Before your if condition, you can add something like:
$del = Change_info_request::find('customer_id', $request->id)->delete();

Eloquent: Scope for Model where latest related Model meets permission

I have a Model Products that has many of the Model Prices.
Every day there is a different price for the product.
Now I am trying to create a scope that gives me all products which latest price is between two values.
I tried this with a whereHas query:
public function scopePriceBetween($query, ...$priceRange) {
return $query->whereHas('price', function ($query) use ($priceRange) {
$query->latestPrice()->whereBetween('price', $priceRange);
})
}
with the scope on the price model
public function scopeLatestPrice($query) {
return $query->latest('date')->limit(1);
}
But this will give me all the products where any price was between the range and not just the latest price.
Is there a way to do this with acceptable performance in eloquent or do I need to add a latest_price column to my product model?
for later price you can use database temp column or you can use redis. but i recommend temp column.
First Solution : Temporary Table
DB::statement("CREATE TEMPORARY TABLE last_prices SELECT prices.* from prices join products on products.id=prices.product_id and prices.id=(select id from prices where prices.product_id=products.id and `prices`.`deleted_at` is null order by `id` desc limit 1);");
$query = Product::select("products.*")
->join("last_prices", "products.id", "last_prices.product_id");
in this example, every task has many jobs, you can query database to make a temporary table and fetch the last_job from jobs;
Second Solution : Using Cache Server
DBMS temp table is fast, but you can gain performance by Cache server (for example redis).
you can store every product last price in cache server by product_id:
public function getLastPriceAttribute(){
//cache for an hour
$p_id = $this->id;
return Cache::tags(['product'])->remember($this->id, 60*60, function () uses ($p_id) {
return Price::where('product_id', $p_id)
->latest()
->first();
});
}
The third solution:
if your price updates are daily and you haven't or don't want to use cache server you can make a database table named last_prices and update it daily with laravel schedule as follow:
in App\Console\Kernel.php :
//suggestion has not tested
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
$updateValues = array();
foreach( Product::all() as $product){
array_push($updateValues , array(
"product_id" => product->id,
"price_value" =>
Price::where('product_id',$product->id)
->latest()
->first()->price_value;
));
}
LastPrices::updateOrInsert($updateValues);
})->dailyAt("05:30"); }
UPDATE
for this:
Product::latestPriceBetween([100,200])->category('electronics');
you can make Suggested Third Solution to have Last_price Table.
and define scope with join, with this nice package : https://github.com/fico7489/laravel-eloquent-join
looks like something like this:
public function scopePriceBetween($query, ...$priceRange) {
return $query->join("last_prices","last_prices.product_id","products.id")->whereBetween('last_prices.value', $priceRange);
}

cakePHP 3 save data in Many to Many relationship

I have Employees and Complexes in a Many to many relationship.I have used the
bake console to generate models, controllers... for Employees and Complexes tables.
My questions is :
-Since I have in my BD The table "complexes_employees", do I have to bake also Model
and controller for this Table too or cakePHP is able to know that it contains the
two foreign keys of Employees and Complexes.
Second question :
-How can I save my data in this Three tables. for my app I have to save employees
per Complex .
// Employees Controller
public function addEmpPerComplex($id_complex){
$emp = $this->Employees->newEntity();
if ($this->request->is('post')) {
$employee = $this->Employees->patchEntity($employee, $this->request->data, ['associated'=>['Complexes._joinData']] );
//here I need to insert the record that contains the employee data in Employees Table
// then I need to insert in "complexes_employees" the ID of Complex sended in parametre of this function and the ID of the new Employee
Thanks for helping me
Do I have to bake also Model and controller for this Table?
No, CakePHP will use the abstract Table class. However, if you need extra information for this relationship, then you will need to create a join model. Check http://book.cakephp.org/3.0/en/orm/associations.html#using-the-through-option
How can I save my data in this Three tables?
As long as your data has the id of a related entity, it will automatically be saved both entity and relation:
$data = [
//employee data,
'complexes' => [
['id' => $id_complex]
]
]
$this->Employees->patchEntity($employee, $data, [
'associated' => ['Complexes']
]);
/*
Saves both the new Employee and the relation
(employeed id and complex id in complexes_employees)
*/
$this->Employees->save($employee);
For more information: http://book.cakephp.org/3.0/en/orm/saving-data.html#saving-belongstomany-associations

Resources