How to Get Order Details per a single User in Laravel 7 - laravel

I am making a multi-vendor ecommerce website using Laravel 7. I am trying to make an Order History page where in a single can user can view only his/her own orders. I am having a problem building the query on my OrderHistoryController. These are the codes on my controller:
$users = User::get();
$orders = Order::find($users);
return view('order-history', compact('orders'));
And I'm trying to loop $orders on my blade file. I have:
#foreach ($orders as $order)
<div>{{ $order->id}}</div>
<div>{{ $order->grand_total}}</div>
#endforeach
I am trying to pass the order id and order grand total to my view. I don't get any error however it shows a different order details from a different customer. How do I do this?

You should use MySQL (or any other database you are using) table relationships and foreign keys.
So, your orders table, should have columns id, user_id, date, and so on. The important thing is user_id column. You want to make that column a foreign key. That basically means that user_id will hold an id value from another table, in this case user. See how to make foreign key columns in laravel migrations here.
Next up is to use Laravel's built in model relationships. You can read more about them here. Basically, in your orders model you want to have a function user which returns $this->belongsTo(App\Models\User::class) and in your user model you want to have a function orders which returns $this->hasMany(App\Models\Order::class) (or whatever the namespace is for both of them).
That way, you can call $user->orders and get a collection of Order models which will contain only the orders of that particular user.
Definitely read the documentation carefully and learn basic concepts of the framework first and how relational databases function!
You can get a lot of this information just by googling it or reading the documentation of Laravel or any other framework you plan on using! Good luck learning :)

Related

Laravel models, database and pivot tables question

Hello I am working with Laravel,
I have to create two simple models, let's say Stores and Books.
Stores can have one or multiple Books and Books can belong to many Stores.
Of course I will use a many to many relationship, with a pivot table.
Books the can have different prices depending the store.
I think a separate table can only complicate things, in my mind the pivot table associating books and stores should have a price column, but pivot tables only contains store_id and book_id.
Should I create a book_prices and associate it with books and to stores? What is the best approach?
You are free and able to set other attributes on your pivot table. You can read more about it in the docs.
https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns
You have to define the relationship accordingly, the following should clarify how this works. In this example you use the many-to-many relationship and add the price column to every retrieved pivot model.
public function books()
{
return $this->belongsToMany(Book::class)
->withPivot('price')
}
For example, you are able to access the pivot column in a loop like this
foreach ($shop->books as $book)
{
echo $book->pivot->price;
}
You can define additional columns for your pivot table in the migration for the pivot table, and then when defining the relationship use withPivot to define the additional columns so they come through in the model:
return $this->belongsToMany(Book::class)->withPivot('price');
(Adapted from the Laravel documentation, see https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns)
Depends on the complexity of your case, but yes, you have two options for it. Let's say that the pivot table is called as book_store:
Directly adds price column to book_store. This is obviously the simpler option. The drawbacks are:
The history of the price changes isn't logged. You'll have to create another table for logging if you want to keep this history information.
Changes made to price will directly change the price of the related book_store record. Meaning that a price is being updated "live" e.g users cannot update the price now but "publish" it some time later just like this example in the doc.
Create a new, different table to store the price. This may seems relatively more complex, but it may also be more future-proof.
Basically, you get 2 things that you miss in the first option above.
Don't think too much about book_store being a pivot table. One way to see it is like this: book_store IS a pivot table from books and stores tables viewpoints, but it's also just a normal SQL table which could relate to any other tables using any kind of relationships.
If you want to implement this, make sure to create a primary-key in the book_store table.
Alast, it all depends on what you need. Feel free to ask if you need more insight about this. I hope this helps.

Laravel get relation by custom value

Model - User
id [999]
name [foo]
Model - Post (without User Foreign Key)
id [1]
unique_key [USR_00000999]
data [bar]
I would like to get all user with related posts (one to many) by using "custom key" value, is this possible with build in eloquent?
I only manage to looping using foreach one by one with
Post::query()
->where('unique_key', sprintf('USR_%08d', $user_id))
->count();
That is not built-into Laravel by default... if you want to know why it's because it's not a common thing that everyone does...
BUT, you can use scope query so you don't need to do the sprintf everytime...
Laravel Query Scopes Documentation
But I want to ask, why wouldn't you just add user_id on your post table and just have an Accessors on your post model for generating the unique_key? That would be much easier on my perspective...
Laravel Accessor Documentation
UPDATE: (See Comment)
Is it possible to have an empty user_id on Posts table?
then populate it when the user is created?
say you have a posts with key of USR_00000999... and you have a user with an id of 999... when you create that user you'll just have to update all posts with key of USR_00000999 to have a user_id of 999...

Laravel/Lumen include a column from pivot table into results of relationship eager loading

In my application a user can add other users to the "favorites" list. All information about favorite users is stored in a table with the following structure:
user_id
favorite_id
In addition, each user has its services with prices. There are users and services tables in my application that are related to each other with service_user table which has the following structure:
user_id
service_id
price
In order to get all favorite users of a particular user with their services and prices I do the following:
$user->favorites()->with('services')->get();
However, there's no price column in each service object of the resulting list of services (this column is located in pivot).
Therefore, I want to know if there's a way to get the price column as part of each service object, instead of being in pivot table. The following question already solves my problem, but I want to know if there is way to do this without map() and/or foreach() to make performance better?
Currently, I have the following solution:
$user->favorites()->with('services')->get()
->map(function ($favorite) {
foreach ($favorite['services'] as &$item) {
$item['price'] = $item->pivot->price;
}
return $favorite;
});

Laravel passing variable from multiple models

I have 2 models
User
Customer
Each user hasMany customers (aka Accounts)
the user model has
public function customer() {
return $this->hasMany('App\Customer', 'id','customer_id');
}
but when i try to output this:
$user->customer->name
i get an error saying:
Undefined property: Illuminate\Database\Eloquent\Collection::$name
When i use this one, i get the entire customers record output in JSON.
$user->customer
So the relationship is working, but obviously i am missing something. I was sure this was the right way to do it. I swear this worked in Laravel4.2 but now that I'm in Laravel 5 it doesn't.
As the error and the below link says, It is returning a collection (hasMany) not a single object, you need to either loop over the collection or do direct access in the collection based on the index.
that is to say... does doing this work?..
$user->customer[0]->name
http://laravel.io/forum/04-10-2014-undefined-property-illuminatedatabaseeloquentcollectionitem
You should loop over customers, if you want display customers in laravel view you can do the following
#foreach
($user->customer as $cust)
{{$cust->name}}
#endforeach

Eloquent select specific columns

I am trying to select specific columns using Laravel's Eloquent but I am having some issues. I just want to SELECT quantity, prices from prices. I have tried
$prices = Price::select(array('quantity', 'price'))->whereMonthAndYearAndType($month,$year,'cpi')
->with(array('product'=>function($query){ $query->select('id','name'); }))
->with(array('market'=>function($query){ $query->select('id','name'); }))->get();
but I am getting Trying to get property of non-object
There is nothing in your code snippet that would produce that error. However, I suspect you are getting the error when you are trying to access fields on the eager loaded product or market relationships without checking for their existence.
A common problem with specifying select statements and eager loading relationships is that the local and foreign keys usually get left out. However, these are the values that Laravel uses to match up all the related models, so they need to be selected, as well.
If price belongsTo a product and price belongsTo a market, then you also need to select the prices.product_id and prices.market_id fields. If price hasOne product or price hasOne market, then you'll need to select the prices.id field, and the corresponding foreign keys on the eager loaded relationships (products.price_id or markets.price_id).
Though, even once this is resolved, it is still a good idea to check to make sure the related record exists before trying to access it. In a hasOne/belongsTo relationship, if the related record doesn't exist, the relationship property will be NULL. If you try to access a field on NULL, you'll get the error you're seeing.

Resources