Laravel hasOne Relation 2 columns - laravel

I have 2 Models first one is(Plan) and the second is (PlanPrice)
I have this columns in table plan_price:
$table->float('price')->comment('Price for one month or one year depends
on country code');
$table->string('country_code')->default('EG');
What I want is to get a plan with price depends on the user country code.

I think you should do this:
return $this->hasOne(PlanPrice::class, 'plan_id')->where('country_code',
$what_ever_your_code_is);

Related

How can I sum two fields from two different tables in laravel in api?

I want to add the price field from the enginestable with the buying_price field from the vehicles table where we have several purchases of vehicles and several engines and I want to sum the final cost for each purchases
I have the following tables
I want to add the price field from the enginestable with the buying_price field from the vehicles table where we have several purchases of vehicles and several engines and I want to sum the final cost for each purchases
I wrote the following command, but I get an error:
$purchase=DB::table('purchases')
->leftjoin('vehicles', 'vehicles.purchase_id', '=','purchases.id')
->leftjoin('engines', 'engines.purchase_id','=','purchases.id')
->leftjoin('suppliers', 'suppliers.id', '=', 'purchases.supplier_id')
->select('purchases.id','suppliers.name','purchases.purchase_date','vehicles.buying_price','engines.price')->get()
->collect('vehicles.buying_price','engines.price')->sum();
return $purchase
this is the the error:
In short, how do I add two values ​​from two different tables and show them in another table?
you can call back of sum instead of collect.
For example Try this:-
$purchase=DB::table('purchases')
->leftjoin('vehicles', 'vehicles.purchase_id', '=','purchases.id')
->leftjoin('engines', 'engines.purchase_id','=','purchases.id')
->leftjoin('suppliers', 'suppliers.id', '=', 'purchases.supplier_id')
->select('purchases.id','suppliers.name','purchases.purchase_date','vehicles.buying_price','engines.price')->get()
->sum(function($data){
return $data->buying_price + $data->price;
});

How to define the following relationship

I am developing a p2p app with laravel. I have two tables namely users and loans.
Firstly, a user can be a lender or borrower.
Then users can have multiple loans and multiple loans belong to multiple users.
Also, a loan can belong to one borrower and also to multiple lenders.
To explain it further, the loan record will be created by the borrower(or the user). Then the system will distribute the loan and assign it to multiple lenders.
Example: Let's say, one borrower wants a loan of 3000. Our system will distribute the loan as 2000 and 1000 (or 1500 and 1500, or 2500 and 500, etc.). Then assign it to two lenders.
Now it could be more lenders or bigger amounts.
So how can I define something like this with laravel eloquent?
Here's what I thought of till now.
Users and loans will have a many-to-many relationship.
Loans table will have a lender_data column which will be an array that contains lender_id and amount.
But I can't really figure out a way to fetch all the loans of a single lender. So how can I do that?
That's a lot of words. Thank you for reading.
First of all, this question is quite vague and doesn't show any code which I think all questions should. Its harder to answer questions like this that don't necessarily have predefined answers.
Personally, I'd look into intermediate table models:
https://laravel.com/docs/8.x/eloquent-relationships#defining-custom-intermediate-table-models
That way you can have a Lenders table, a Loan table, a Users table, and this "in between" table that could be something like a LoanAmount table. The LoanAmount table is mostly a pivot table (allowing the many to many relationship between Lenders and Loans), however it can also store data like:
loan_id lender_id amount
1 1 1000
1 2 1000
Then the loan table would just be
user_id amount
1 2000
So a User can have many Loans, but it's the Loans that can have many LoanAmounts.
I'd go with next:
class User extends Model
{
public function loans()
{
return $this->belongsToMany(Loan::class)->using(LoanUser::class)->withPivot(['amount', 'percentage']);
}
}
class Loan extends Model
{
public function users()
{
return $this->belongsToMany(User::class)->using(LoanUser::class)->withPivot(['amount', 'percentage']);
}
}
class LoanUser extends Pivot
{
protected $with = [
'landers',
];
public function landers()
{
return $this->belongsToMany(Lander::class)->withPivot(['percentage']);
}
}
class Lander extends Model
{
public function loanUsers()
{
return $this->belongsToMany(LoanUser::class)->withPivot(['percentage']);
}
}
In loan_user pivot table you should make field called percentage that will go to user from full amount. In second pivot between LoanUser and Lander lander_loan_user you should also need percentage field that you would assign to each lander_loan_user relation. It would be second pivot table data.
After you save loan_user data, you would need to attach landers to first pivot model (second pivot table doesn't require pivot model per description). Since there are eager loaded landers to pivot model, when you query some user and their loan
$user = User::where(['loan.amount' => 3000])->first();
$user->pivot->landers;// will get you related landers
You already have full amount in first pivot table and with percentage from same table you know how much user (borrower) gets and in pivot's relation to landers table you will know how much each lander gets from that loan.
It is like "T" relation where upper ends of 't' letter are Loan and User, that crossroad is LoanUser pivot and lower end (base) of the letter 't' are landers.
To avoid hard time as much as possible, keep up with eloquent's convention (check good practice here) and for example, instead of borrower_id call that loan_id, also pivot table to be loan_user (pay attention on pivot singular).
This was written from top of head and not tested but this is the idea/way how task can/should be finished.

Laravel Eloquent - Sum of a column values for multiple records from related data

I have the following models: User, Order, OrderPayment
whereby each user has many orders, and each order has many order payments.
The orderPayment model has the attribute "total_paid"
I would like to get the sum of the user's total paid for all his orders.
eg:
user has 3 orders.
the first order has the two following payment records: 5$ and 4$.
the second order has one payment of 10$
the third order has two payment records of 1$ and 4$
the total sum i want is 5 + 4+ 10+ 1+ 4 = 24$.
I have tried the following but it's not working at all :
$user->orders->orderpayment->sum('total_paid');
but i get this error
Property [orderPayment] does not exist on this collection instance
Since you want to sum values from the OrderPayment model, it is easier to start there. Try to write it like this:
OrderPayment::whereHas('order.user', function($query) use ($userId) {
$query->whereId($userId);
})->sum('total_paid');
Make sure all the relations are defined well.
Try:
$user->orders->orderpayment()->sum('total_paid');

Laravel 5 hasManyThrough repeating row content

I have the following Database tables:
tour
idtour
other_columns
day
idday
other_columns
tour_has_day
idtour
idday
Each tour has many days, and the days can be used in other tours
So, in the Tour.php model I add this function:
function days () {
return $this->hasManyThrough('App\Day', 'App\Tour_has_day', 'idtour', 'idday');
}
It gives me the correct number of related days but all rows have the same content
I debug the query that it returns:
select
`day`.*,
`tour_has_day`.`idtour`
from `day`
inner join
`tour_has_day` on `tour_has_day`.`idtour` = `day`.`idday`
where
`tour_has_day`.`idtour` = '1'
And it returns
You'll need a many-to-many relation with a pivot table like the one you have for that. The has-many-through relation is for when you have a parent and a child, and the child is the parent of another child.

Laravel Eloquent how to get the second or third record?

I have an Order and a Product models.
"Order" HasMany Product (and Product belongsTo Order)...
Let's say I want to display the 3 products of my order, how to do that ?
I know the first could be retrieved like $order->products->first()... but how to retrieve the second and third product?
I tried $order->products->find(1) but "1" represents the id of the product... which I don't want to know...
$order->products()->skip(1)->first();//Second row
$order->products()->skip(2)->first();//Third row
....
Is more performant than loading all products and getting only first, second, ecc..
Instead if you want both second and third, you can get only them in a single query without load other rows, with similar approach:
$order->products()->skip(1)->take(2)->get(); //Skip first, take second and third
I finally found the solution, this is the correct syntax:
$order->products->get(0)->name; will return the first record
$order->products->get(1)->name; will return the second record
$order->products->get(2)->name; will return the third record
And so on...
$order->products()->skip(1)->take(1)->first(); //Second row
$order->products()->skip(2)->take(1)->first(); //Third row
$order->products()->orderBy('salary','desc')->skip(1)->take(1)->first(); //Second highest salary row
$order->products()->orderBy('salary','desc')->skip(2)->take(1)->first(); //Third highest salary row
Say you want a second product from Eloquent Collection
if you are sure that the array keys are same as array indexes, do that
$order->products->get(1)->name;
if you need the second item and you are not sure about the array keys, do this
$order->products->slice(1, 1)->first()->name;
You can simply try this :
$order->products->take(3)->get();

Resources